I've been searching the solution of this problem for weeks now and still blocked...
I need to use the program "quser" in powershell but in my C# program.
If I run "quser" just in the powershell console I have a result.
But when I execute a powershell script with "quser", it returns nothing... That's weird.
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
String script = "$re = '(\\S+)\\s+?(\\S*)\\s+?(\\d+)\\s+(\\S+)\\s+(\\S+)\\s+(\\d+\\/\\d+\\/\\d+\\s+\\d+:\\d+)'\n"
+ "query user /server:"+machine+" | Where-Object { $_ -match $re } | ForEach-Object {\n"
+ "New-Object -Type PSCustomObject -Property #{"
+ "'Username' = $matches[1]\n"
+ "'LogonTime' = $matches[6]\n"
+ "}\n"
+ "} | Select-Object Username, LogonTime | ForEach-Object { Write-Output (\"{0} is connected from {1}\" -f $_.Username, $_.LogonTime) }";
ps.AddScript(script);
Collection<PSObject> result = ps.Invoke();
ps.Dispose();
runspace.Close();
runspace.Dispose();
Console.WriteLine(result.Count);
The result of the ps.Invoke() is empty.
But when I run this code from a powershell console it works.
Also another weird thing, it works in remote powershell :
String script = "$re = '(\\S+)\\s+?(\\S*)\\s+?(\\d+)\\s+(\\S+)\\s+(\\S+)\\s+(\\d+\\/\\d+\\/\\d+\\s+\\d+:\\d+)'\n"
+ "query user | Where-Object { $_ -match $re } | ForEach-Object {\n"
+ "New-Object -Type PSCustomObject -Property #{"
+ "'Username' = $matches[1]\n"
+ "'LogonTime' = $matches[6]\n"
+ "}\n"
+ "} | Select-Object Username, LogonTime | ForEach-Object { Write-Output (\"{0} is connected from {1}\" -f $_.Username, $_.LogonTime) }";
string shellUri = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
System.Security.SecureString sString = new System.Security.SecureString();
foreach (char passwordChar in password.ToCharArray())
{
sString.AppendChar(passwordChar);
}
PSCredential credential = new PSCredential(username, sString);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, machine, 5985, "/wsman", shellUri, credential);
List<String> scriptOutput = new List<String>();
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runspace.Open();
Pipeline pipe = runspace.CreatePipeline();
pipe.Commands.AddScript(script);
Collection<PSObject> result = pipe.Invoke();
foreach (PSObject line in result)
{
scriptOutput.Add(line.ToString());
}
pipe.Dispose();
runspace.Close();
}
foreach(String line in scriptOutput)
{
Console.WriteLine(line);
}
It returns the connected user.
The fact is that I don't want to logged into the machine in order to see the conncted users. (because it works in the powershell console)
If someone could help me please.
Thanks.
Related
I need to make a system for domain change and it is necessary to execute this code via C #, but I have tried everything and I cannot.
To run the script in PowerShell, you must initialize it as an administrator. In PowerShell, it works without problems.
Code in Power Shell:
$domain = "NameDomain"`enter code here`
$password = "pwd" | ConvertTo-SecureString -asPlainText -Force
$username = "$domain\User"
$credential = New-Object System.Management.Automation.PSCredential($username,$password)
Add-Computer -DomainName $domain -Credential $credential -Restart -Force
Code in C#;
var scriptfile = #"$domain = ""dominio""; $password = ""psw"" | ConvertTo-SecureString -asPlainText -Force; $username = ""domain\user""; $credential = New-Object System.Management.Automation.PSCredential($username,$password); Add-Computer -DomainName $domain -Credential $credential -Restart -Force";
Method used:
private string RunScript(string script)
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pip = runspace.CreatePipeline();
pip.Commands.AddScript(script);
pip.Commands.Add("Out-String");
Collection<PSObject> results = pip.Invoke();
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject pSObject in results)
stringBuilder.AppendLine(pSObject.ToString());
return stringBuilder.ToString();
}
I connect to Exchange Online via C# and can run a Get-Mailbox command without problem. But when I try
Get-Mailbox | Where LitigationHoldEnabled -eq $true
I get an error
The term 'where.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
The command runs just fine in PowerShell.
What am I missing?
PSCredential credential = new PSCredential("xxxxx#yyyyyyyy.de", secpassword);
string connectionUri = "https://outlook.office365.com/powershell-liveid/";
Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace( );
PowerShell powershell = PowerShell.Create();
PSCommand command = new PSCommand();
command.AddCommand("New-PSSession");
command.AddParameter("ConnectionUri", new Uri(connectionUri));
command.AddParameter("ConfigurationName", "Microsoft.Exchange");
command.AddParameter("Credential", credential);
command.AddParameter("Authentication", "Basic");
command.AddParameter("AllowRedirection", true);
powershell.Commands = command;
runspace.Open();
powershell.Runspace = runspace;
Collection<System.Management.Automation.PSObject> result = powershell.Invoke();
if (powershell.Streams.Error.Count > 0 || result.Count != 1)
{
powershell.Dispose();
runspace.Dispose();
}
command = new PSCommand();
command.AddCommand("Invoke-Command");
command.AddParameter("ScriptBlock", System.Management.Automation.ScriptBlock.Create("Get-Mailbox | Where-Object LitigationHoldEnabled - eq $true"));
command.AddParameter("Session", result[0]);
powershell.Commands = command;
var Searches = powershell.Invoke();
....
powershell.Dispose();
runspace.Dispose();
I am trying to run a powershell script in c#
here is the first test script
param(
[string] $computer,
[string] $password
)
out-file -filepath C:\File\parameter.txt -inputobject $computer -encoding ASCII -width 50 -Append
out-file -filepath C:\File\params.txt -inputobject $password -encoding ASCII -width 50 -Append
out-file -filepath C:\File\Sys32.txt -inputobject $password -encoding ASCII -width 50 -Append
and here is my C# supposed to run the powershellscript
private void testRunningPowershell()
{
string mypass = gettingPass();
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
runspace.SessionStateProxy.Path.SetLocation("C:\\Users\\robert\\Desktop\\Titanium\\");
RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
//runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
// create a pipeline and feed it the script text (AddScript method) or use the filePath (Add method)
using (Pipeline pipeline = runspace.CreatePipeline())
{
Command command = new Command(#"C:\Users\robert\Desktop\Titanium\Titanium2.ps1");
dictionaryParams.Remove("FriendlyName");
foreach (var item in dictionaryParams)
{
if (item.Key == (string)comboBoxScreen.SelectedItem)
{
CommandParameter testParam = new CommandParameter(null, item.Value);
CommandParameter testParam2 = new CommandParameter(null, mypass);
command.Parameters.Add(null, testParam);
command.Parameters.Add(null, testParam2);
}
}
pipeline.Commands.Add(command);
var results = pipeline.Invoke();
ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in results)
{
Hashtable ht = p.ImmediateBaseObject as Hashtable;
ri.ReturnText = (string)ht["ComputerName"];
ri.ReturnText = (string)ht["password"];
}
runspace.Close();
}
}
}
my purpose is to test if the cmdlet is run with the right parameters
I've got a windows form app that allow the user to choose the parameter
I would like to get my parameter value written in Text File (.txt)
instead I am getting this
System.Management.Automation.Runspaces.CommandParameter
instead of the parameter's value choosen
When I run the code below I get the following error at Response.Write( result.Properties["name"].Value);. "use the 'new' keyword to create and object instance."
I can't figure out how to fix this problem.
String sEmailAddress;
String sPassword;
sEmailAddress = Request.QueryString["value1"];
sPassword = Request.QueryString["value2"];
lbl1.Text = sEmailAddress + " " + sPassword;
SecureString sSecurePW = new SecureString();
foreach (char c in sPassword.ToCharArray())
sSecurePW.AppendChar(c);
PSCredential Credential = new PSCredential(sEmailAddress, sSecurePW);
PowerShell powershell = PowerShell.Create();
powershell.Runspace.SessionStateProxy.SetVariable("cred", Credential);
powershell.AddScript("$s = New-PSSession -ComputerName ExchDC01 -Credential $cred -Authentication Kerberos");
powershell.AddScript("invoke-command -session $s -scriptblock {Get-ADOrganizationalUnit -LDAPFilter '(name=*)' -SearchBase 'OU=TENANTS,DC=lab,DC=local' -SearchScope OneLevel | ft Name}");
// Collection<PSObject> results = powershell.Invoke();
foreach (PSObject result in powershell.Invoke())
{
Response.Write(result.Properties["name"].Value); //<-- Error:use the 'new' keyword to create and object instance.
}
}
Thanks in advance
I have tried executing AD commandlets in powershell using C# from the same machine. This works fine.
static void Main(string[] args)
{
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ImportPSModule(new string[] { "activedirectory" });
Runspace myRunSpace = RunspaceFactory.CreateRunspace(iss);
myRunSpace.Open();
Pipeline pipeLine = myRunSpace.CreatePipeline();
Command myCommand = new Command("Get-ADUser");
myCommand.Parameters.Add("Filter", "sAMAccountName -eq 'user1'");
//myCommand.Parameters.Add("IncludeDeletedObjects");
pipeLine.Commands.Add(myCommand);
//Command restoreCommand = new Command("Restore-ADObject");
//pipeLine.Commands.Add(restoreCommand);
Console.WriteLine("Before Invoke");
Collection<PSObject> commandResults = pipeLine.Invoke();
Console.WriteLine("After Invoke");
foreach (PSObject cmdlet in commandResults)
{
//Console.WriteLine("Inside foreach");
string cmdletName = cmdlet.BaseObject.ToString();
System.Diagnostics.Debug.Print(cmdletName);
Console.WriteLine(cmdletName);
}
Console.ReadLine();
}
But while trying to run the same command remotely using the invoke command it gives the error The term 'Get-ADUser' is not recognized as the name of a cmdlet, function, script file, or operable program.
The following is my program :
static void Main(string[] args)
{
string shellUri = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
string userName = "Domain\\Administrator";
string password = "Password";
SecureString securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
PSCredential credential = new PSCredential(userName, securePassword);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, "machinename", 5985, "/wsman", shellUri, credential);
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runspace.Open();
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = runspace;
PSCommand new1 = new PSCommand();
new1.AddCommand("Get-ADUser");
new1.AddParameter("identity", "CN=user1,DC=example,DC=com");
powershell.Commands = new1;
Collection<PSObject> results = powershell.Invoke();
foreach (PSObject obj in results)
{
PSMemberInfoCollection<PSPropertyInfo> propInfos = obj.Properties;
Console.WriteLine("********************");
foreach (PSPropertyInfo propInfo in propInfos)
{
string propInfoValue = (propInfo.Value == null) ? "" : propInfo.Value.ToString();
Console.WriteLine("{0} --> {1}", propInfo.Name, propInfoValue);
}
}
}
}
}
How can I achieve calling AD commandlets remotely?
Is there a way to invoke commands remotely using InitialSessionState rather than WSManConnectionInfo .
If I use invoke-command -computername $DC -ScriptBlock {Remove-ADUser -identity "user1"} -credential $cred - i get the error The term 'Remove-ADUser' is not recognized as the name of a cmdlet, function, script file, or operable program.
But it is possible to use command Remove-ADUser -identity "user1" -server $DC -credential $cred .How to directly execute the AD command in powershell from C# client?
You need to import the ActiveDirectory module in the remote runspace before executing the AD command e.g.:
powershell.Commands.AddCommand("Import-Module").AddArgument("ActiveDirectory");
powershell.Invoke();
powershell.Commands.Clear();