Error message when running a c# powershell code - c#

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

Related

Can not execute Powershell Script in .Net MVC Application

I have a .Net MVC application which need to check and get some information from another server via powershell command with code shown below. But app can not get information
try
{
string un = #"domainA\domainUserName";
System.Security.SecureString pw = new System.Security.SecureString();
string password = "";
string exchangeServerName = "ServerAdress/powershell";
foreach (char ch in password)
{
pw.AppendChar(ch);
}
using (PowerShell _powerShell = PowerShell.Create())
{
var credential = new PSCredential(un, pw);
_powerShell.Runspace.SessionStateProxy.SetVariable("Credential", credential);
_powerShell.AddScript($"$Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri {exchangeServerName} -Credential $Credential -Authentication Kerberos -AllowRedirection");
_powerShell.AddScript("Import-PSSession $Session");
_powerShell.Invoke();
_powerShell.AddScript(#"get-mailbox -identity " + mail + " | Select-Object ProhibitSendReceiveQuota");
var results = _powerShell.Invoke();
string size = "";
string used = "";
string size2 = "";
foreach (PSObject obj in results)
{
size = (obj.Properties["ProhibitSendReceiveQuota"].Value.ToString());
}
_powerShell.AddScript(#"Get-MailboxStatistics -Identity " + mail + " | Select-Object Totalitemsize,DatabaseProhibitSendQuota");
var results2 = _powerShell.Invoke();
_powerShell.AddScript("Remove-PSSession $Session");
_powerShell.Invoke();
//
}
}
Target server and source server are in different domains.
In local running app wroks perfectly. What can be cause this issue and how can I resolve issue.
Thank you.

quser (query user) no result in powershell c#

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.

Powershell remote commandlet from c# for cim-session

using (PowerShell pInst=PowerShell.Create()) // implements Idisposable
{
string username = Console.ReadLine();
System.Security.SecureString pwd = getPassword();
PSCredential credential = new PSCredential(username, pwd);
pInst.Runspace.SessionStateProxy.SetVariable("cred", credential);
//pInst.AddScript("$cred;");
//pInst.AddScript("$session= New-CimSession -ComputerName anksahawin8a $cred");
//pInst.AddScript("$session;");
//pInst.AddScript("param($param1) $d = get-date;"+"$d; $s; $param1; get-service");
//.AddParameter("param1","Ankit");
//pInst.Invoke(); // Synchronous Invocation
pInst.AddScript("$session= New-CimSession -ComputerName anksahawin8a -Credential $cred;");
//psOutput = pInst.Invoke();
pInst.AddScript("$session;");
Collection<PSObject> psOutput = pInst.Invoke();
//psOutput = pInst.Invoke();
if(pInst.Streams.Error.Count>0) // Errors
{
}
foreach(PSObject pso in psOutput)
{
Console.WriteLine(pso);
if (pso != null)
{
//String result=pso.Members["Value"].Value.ToString();
Console.WriteLine(pso.BaseObject.GetType().FullName);
Console.WriteLine(pso.BaseObject.ToString() + "\n");
}
}
Console.WriteLine("Hello");
}
This code is not working. Whereas
pInst.AddScript("$session= New-CimSession");
for local computer works...

Using C# To Return Data From PowerShell

I am trying to return a PrimarySMTPAddress to a variable, in Powershell the code I run is this:
Get-Mailbox -identity UserName | select PrimarySMTPAddress
And it returns the correct value, I want to get this in my C# Code, I have done the following:
string getPrimarySMTP = "Get-Mailbox -identity " + username + "| select PrimarySMTPAddress";
var runSpace = RunspaceFactory.CreateRunspace(Utility.CreateConnectionInfo());
runSpace.Open();
var pipeline = runSpace.CreatePipeline();
pipeline.Commands.AddScript(getPrimarySMTP);
var primarySmtp = pipeline.Invoke();
runSpace.Dispose();
I would Expect this to return the same data, but it doesn't. I just get an exception:
The term 'select' 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.
Is this the way to return values from a powershell command?
For what version of Exchange ? for 2010 up you need to use Remote Powershell see https://msdn.microsoft.com/en-us/library/office/ff326159%28v=exchg.150%29.aspx . (even in 2007 your code would work because you haven't loaded the snapin).
Cheers
Glen
You may need to add an additional space character before the pipe. It' being concatenated to the username, with the resulting string becoming ... -identity UserName| select ..."
Here's the corrected statement:
string getPrimarySMTP = "Get-Mailbox -identity " + username + " | select PrimarySMTPAddress";
Thanks for asking this question, it helped me to lead to the answer I needed. My code resulted in the following using RemoteRunspace to an Exchange 2013 environment:
try
{
var target = new Uri(Uri);
SecureString PSPassword = new SecureString();
foreach (char c in ConfigurationManager.AppSettings["Password"])
{
PSPassword.AppendChar(c);
}
//var cred = (PSCredential)null;
PSCredential cred = new PSCredential(ConfigurationManager.AppSettings["Username"], PSPassword);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(target, shell, cred);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Default;
connectionInfo.OperationTimeout = 1 * 60 * 1000; // 4 minutes.
connectionInfo.OpenTimeout = 1 * 30 * 1000; // 1 minute.
using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
remoteRunspace.Open();
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = remoteRunspace;
powershell.AddScript(PSSnapin);
powershell.Invoke();
powershell.Streams.ClearStreams();
powershell.Commands.Clear();
Pipeline pipeline = remoteRunspace.CreatePipeline();
Command getMailBox = new Command("Get-Mailbox");
getMailBox.Parameters.Add("Identity", Username);
Command cmd = new Command("Select-Object");
string[] Parameter = new string[] { "PrimarySMTPAddress" };
cmd.Parameters.Add("Property", Parameter);
pipeline.Commands.Add(getMailBox);
pipeline.Commands.Add(cmd);
Collection<PSObject> results = pipeline.Invoke();
primarySMTPAddress = results[0].ToString();
primarySMTPAddress = primarySMTPAddress.ToUpper().Replace("#{PRIMARYSMTPADDRESS=", "");
primarySMTPAddress = primarySMTPAddress.ToUpper().Replace("}", "");
}
remoteRunspace.Close();
}
return primarySMTPAddress;
}
catch
{
return "Error";
}
Hope this helps anyone in future.

Error while running AD commandlets in powershell from C#

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();

Categories

Resources