Need help converting PowerShell to C# code - c#

So i have this powershell code:
try{
$ComputerWMIObject = Get-WmiObject Win32_ComputerSystem -ComputerName "$oldComputerName" -Authentication 6
if ( $ComputerWMIObject ){
$result = $ComputerWMIObject.Rename("$newComputerName", $ADUserPassword , $ADUserName )
switch($result.ReturnValue)
{
0 {
if ( $Restart.IsChecked ) {
Get-WmiObject Win32_OperatingSystem -ComputerName "$oldComputerName" | ForEach-Object {$restart = $_.Win32Shutdown(6)}
$ResultText.Text = "Computer $oldComputerName was renamed to $newComputerName and restarted"
} else {
$ResultText.Text = "Computer $oldComputerName was renamed to $newComputerName restart computer to finish"
}
}
5 { $ResultText.Text = "Computer was not renamed. Please check if you have admin permissions (ReturnCode 5)" }
default { $ResultText.Text = "ReturnCode $($result.ReturnValue)"}
}
}else{
$ResultText.Text = "Couldn't create WMI Object on $oldComputerName"
}
}catch{
$ResultText.Text = $_
}
I'm trying to convert this to C# and can't find a way to do this. I just don't understand how to create WMI object.
It would be very helpful if you can post and example on how to do this.
I've read this Remotely change computer name for a Windows Server 2008 machine using C#? topic. And it throws an exception may be its because of this line:
Authentication = AuthenticationLevel.PacketPrivacy
I'm using System.Net.Security namespace and as it's stated in comment PacketPrivacy exists only there.
Since I can't ask there because I have low rating I've asked again.
Would be grateful if any one can help me.
PS: I know this can be done using NETDOM but I would prefer using WMI object.
ADDED:
I'm trying to use this:
var remoteControlObject = new ManagementPath
{
ClassName = "Win32_ComputerSystem",
Server = oldName,
Path = oldName + "\\root\\cimv2:Win32_ComputerSystem.Name='" + oldName + "'",
NamespacePath = "\\\\" + oldName + "\\root\\cimv2"
};
var conn = new ConnectionOptions
{
Authentication = AuthenticationLevel.PacketPrivacy,
Username = accountWithPermissions.Domain + "\\" + accountWithPermissions.UserName,
Password = accountWithPermissions.Password
};
var remoteScope = new ManagementScope(remoteControlObject, conn);
var remoteSystem = new ManagementObject(remoteScope, remoteControlObject, null);
ManagementBaseObject newRemoteSystemName = remoteSystem.GetMethodParameters("Rename");
var methodOptions = new InvokeMethodOptions();
newRemoteSystemName.SetPropertyValue("Name", newName);
newRemoteSystemName.SetPropertyValue("UserName", accountWithPermissions.UserName);
newRemoteSystemName.SetPropertyValue("Password", accountWithPermissions.Password);
ManagementBaseObject outParams = remoteSystem.InvokeMethod("Rename", newRemoteSystemName, null);
And I get this error Server RPC is unavailable. (Exception HRESULT: 0x800706BA) here:
ManagementBaseObject newRemoteSystemName = remoteSystem.GetMethodParameters("Rename");
ADDED2:
Ok, I guess I found out what causes an error.
i've changed original conn User name from
Username = oldName + "\\" + accountWithPermissions.UserName,
to
Username = accountWithPermissions.Domain + "\\" + accountWithPermissions.UserName,
and error happens, if I use old code I get ACCESS_IS_DENIED and that's correct because that user doesn't have rights.
So what's wrong if I use Domain\User may be I should change NamespacePath in remoteControlObject to be able to work with domain user authentication?

I was unable to find a way resolve this issue and no one seems to have an answer.
So I've solved this by using NETDOM when Server RPC is unavailable. (Exception HRESULT: 0x800706BA) actually any error happens I will add access denied check so it won't try NETDOM when this happens;
var remoteControlObject = new ManagementPath
{
ClassName = "Win32_ComputerSystem",
Server = oldName,
Path = oldName + "\\root\\cimv2:Win32_ComputerSystem.Name='" + oldName + "'",
NamespacePath = "\\\\" + oldName + "\\root\\cimv2"
};
string domain = accountWithPermissions.Domain;
string user = accountWithPermissions.UserName;
var conn = new ConnectionOptions
{
Authentication = AuthenticationLevel.PacketPrivacy,
Username = domain + "\\" + accountWithPermissions.UserName,
Password = accountWithPermissions.Password
};
var remoteScope = new ManagementScope(remoteControlObject, conn);
var remoteSystem = new ManagementObject(remoteScope, remoteControlObject, null);
try
{
ManagementBaseObject newRemoteSystemName = remoteSystem.GetMethodParameters("Rename");
newRemoteSystemName.SetPropertyValue("Name", newName);
newRemoteSystemName.SetPropertyValue("UserName", accountWithPermissions.UserName);
newRemoteSystemName.SetPropertyValue("Password", accountWithPermissions.Password);
ManagementBaseObject outParams = remoteSystem.InvokeMethod("Rename", newRemoteSystemName, null);
}
catch (Exception e)
{
this.Res.Inlines.Add(string.Format("Ошибка:\n" + e.Message + "\n"));
this.Res.Inlines.Add(string.Format("Пробуем переименовать используя NETDOM\n"));
bool restart = false;
PowerNETDOM(oldName, newName, accountWithPermissions, restart);
}
Server RPC is unavailable. (Exception HRESULT: 0x800706BA) is happening not because my changes to the script. This error if fired only by few PC's as I found out it can happen in many cases more about this here: Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) . And changing settings on a remote PC makes me go and check the settings directly from that PC. In that case I can just rename PC not even trying to find out what this happening. That's why I do use NETDOM because for some reason it doesn't have problems renaming that PC remotely.
private static void PowerNETDOM(String oldName, String newName, NetworkCredential accountWithPermissions, bool restart)
{
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript
(
"param($Restart,$oldComputerName,$newComputerName,$ADUserPassword,$ADUserName);" +
"function ConvertTo-Encoding ([string]$From, [string]$To){" +
" Begin{ $encFrom = [System.Text.Encoding]::GetEncoding($from);$encTo = [System.Text.Encoding]::GetEncoding($to); }" +
" Process{ $bytes = $encTo.GetBytes($_);$bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes);$encTo.GetString($bytes)}" +
"}" +
"$tmp = NETDOM RENAMECOMPUTER $oldComputerName /NewName:$newComputerName /ud:$ADUserName /pd:$ADUserPassword /Force $res_text | ConvertTo-Encoding \"cp866\" \"windows-1251\";" +
"$tmp > C:\\Temp\\rename.txt;$tmp;"
);
PowerShellInstance.AddParameter("restart", restart);
PowerShellInstance.AddParameter("newComputerName", newName);
PowerShellInstance.AddParameter("oldComputerName", oldName.ToString());
PowerShellInstance.AddParameter("ADUserPassword", accountWithPermissions.Password);
PowerShellInstance.AddParameter("ADUserName", accountWithPermissions.Domain + "\\" + accountWithPermissions.UserName);
PowerShellInstance.Invoke();
}
}

Related

DirectoryEntry CommitChanges returns Exception has been thrown by the target of an invocation on server 2019

I tried to create reset password and user creation functions for Active Directory. On my PC with below code is works just fine without any error. But when I publish to the server, I received error: Exception has been thrown by the target of an invocation.
ADResult hasil = new ADResult();
DirectoryEntry de = new DirectoryEntry(_path, _adminID, _adminPassword, AuthenticationTypes.Secure);
DirectorySearcher ds = new DirectorySearcher(de);
string query = string.Format("(&(objectCategory=person)(sAMAccountName={0}))", user.userID);
ds.Filter = query;
ds.Sort.PropertyName = "CN";
ds.SearchScope = SearchScope.Subtree;
ds.CacheResults = false;
try
{
SearchResult sr = ds.FindOne();
if (sr == null)
{
hasil.errorCode = -1;
hasil.result = "User name not found in this domain.";
}
else
{
DirectoryEntry userCredentials = sr.GetDirectoryEntry();
userCredentials.Invoke("SetPassword", new Object[] { user.password });
userCredentials.CommitChanges();
userCredentials.Close();
hasil.errorCode = 0;
hasil.result = "Password for " + user.userID + " changed successfully.";
}
}
catch (Exception e)
{
hasil.errorCode = -1;
hasil.result = e.Message + "<br/>" + e.StackTrace + "<br/>" + e.Source;
}
return hasil;
Is there something configuration/settings that I missed on the server side?
I changed my code using
UserPrincipal
instead of
DirectoryEntry
and it works perfectly.
I use this code:
PrincipalContext PrincipalContext4 = new PrincipalContext(ContextType.Domain, "full_domain_name.com", "OU=User_OU,DC=domain_name,DC=co,DC=id", _adminID, _adminPassword);
UserPrincipal UserPrincipal1 = new UserPrincipal(PrincipalContext4, user.userID, user.password, true);
//User Logon Name
UserPrincipal1.UserPrincipalName = user.userID;
UserPrincipal1.Name = user.firstName + " " + user.lastName;
UserPrincipal1.GivenName = user.firstName;
UserPrincipal1.Surname = user.lastName;
UserPrincipal1.DisplayName = user.firstName + " " + user.lastName;
UserPrincipal1.Enabled = true;
UserPrincipal1.Save();
I still don't know why I use DirectoryEntry is not working on windows server 2019
That't not the exact error message,real error must be wrapped.You can write loggers or event logging after lines which you think could be culprit.You can check event log on that server if you can find elaborated stack Trace. You can check that user have admin privilege for that server to lookup in AD.

NT Authority\Anonymous Logon throws connecting through WMI Connection from Web Server

I have Web,APP,DB Server
App Server which has a Exe it will do some operation .
when I am trying to Trigger a Exe which is in App Server through WMI Connection from Webserver please refer below code
public void RunProcessOnRemoteMachine(string inputFolder, string ProcessName, string AppRun, string isRegression, string TemplateID, string isPreProcess, string UserLoginName, string DocYear,string remoteMachine,string strPathToTheExe)
{
string usernameAndDomain = "";
string password = "";
try
{
ConnectionOptions connOptions = new ConnectionOptions();
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
if (Environment.MachineName.ToUpper() != remoteMachine.ToUpper())
{
}
ManagementScope manScope = new ManagementScope(String.Format(#"\\{0}\ROOT\CIMV2", remoteMachine), connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = strPathToTheExe + " " + "\"" + inputFolder + "\" \"" + ProcessName + "\" \"" + AppRun + "\" \"" + isRegression + "\" \"" + TemplateID + "\" \"" + isPreProcess + "\" \"" + UserLoginName + "\" \"" + DocYear+"\"";
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null );
Cls_ErrorLog.Writelog("Creation of the process returned: " + outParams["returnValue"]);
Cls_ErrorLog.Writelog("Process ID: " + outParams["processId"]);
}
catch (Exception ex)
{
Cls_ErrorLog.Writelog("Exception occured in method RunProcessOnRemoteMachine : " + ex.Message + " - " + ex.StackTrace);
}
finally
{
}
}
I set Integrated Security=True in my Exe Config and Web config and also i added that user in Sql Server Logins and gave the rights.
After made a Connection that EXe is Running with same Credential(what we set in Identity in IIS) in Appserver But it could not connect a database connection with same credentials
it throws Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON. but when we track the exe which is running with same credentials
when we run a Exe manually in App Server its works
So Please Suggest a Solutions
Thanks in advance

Windows Management Instrumentation msi install remote machine

I'm trying to install a msi on a remote machine , i changed DCOM Config to get access from my machine when using methode install of win32_product it fails with return output 1601 ( that means that Windows Installer service could not be accessed )
i did some research in the net , and run the service manually using services.msc
and did msiexec / unreg and msiexec /register , still not working
ps: both machines a running on windows 10
here is my code
Ps : i used the same code for win32_Bios to get SerialNumber and it works
try
{
\\machine is the name of the computer
string PackageLocation = #"\\" + machine + msi;
ConnectionOptions connection = new ConnectionOptions();
connection.Username = username;
connection.Password = password;
connection.Impersonation = ImpersonationLevel.Impersonate;
connection.Authentication = AuthenticationLevel.Default;
connection.EnablePrivileges = true;
//define the WMI root name space
ManagementScope scope =
new ManagementScope(#"\\" + machine + #"\root\CIMV2", connection);
//define path for the WMI class
ManagementPath p =
new ManagementPath("Win32_Product");
//define new instance
ManagementClass classInstance = new ManagementClass(scope, p, null);
// Obtain in-parameters for the method
ManagementBaseObject inParams = classInstance.GetMethodParameters("Install");
// Add the input parameters.
inParams["AllUsers"] = true; //to install for all users
inParams["Options"] = ""; //paramters must be in the format “property=setting“
inParams["PackageLocation"] = #"c:\install\installer.msi";
//source file must be on the remote machine
// Execute the method and obtain the return values.
ManagementBaseObject outParams = classInstance.InvokeMethod("Install", inParams, null);
// List outParams
string retVal = outParams["ReturnValue"].ToString();
string msg = null;
switch (retVal)
{
case "0":
msg = "The installation completed successfully.";
break;
case "2":
msg = "The system cannot find the specified file. \n\r\n\r" + msi;
break;
case "3":
msg = "The system cannot find the path specified. \n\r\n\r" + msi;
break;
case "1619":
msg = "This installation package \n\r\n\r " + msi + "\n\r\n\rcould not be opened, please verify that it is accessible.";
break;
case "1620":
msg = "This installation package \n\r\n\r " + msi + "\n\r\n\rcould not be opened, please verify that it is a valid MSI package.";
break;
default:
msg = "Please see... \n\r\n\r http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/error_codes.asp \n\r\n\rError code: " + retVal;
break;
}
// Display outParams
Console.WriteLine(msg, "Installation report");
}
catch (ManagementException me)
{
Console.WriteLine(me.Message + "Management Exception");
}
catch (COMException ioe)
{
Console.WriteLine(ioe.Message, "COM Exception");
}
}

How to enable a user to access vpn in active directory

how to enable a user to access vpn in active directory using c# programming language.
string username = "Abc user";
string _path;
string _filterAttribute;
try
{
DirectoryEntry myLdapconnection=new DirectoryEntry("domain");
myLdapconnection.Path = "LDAP://OU=,OU=,DC=,DC=,DC=";
myLdapconnection.AuthenticationType = AuthenticationTypes.Secure;
object obj = myLdapconnection.NativeObject;
DirectorySearcher search = new DirectorySearcher(myLdapconnection);
search.Filter = "(cn=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
s="True";
if (null == result)
{
s= "false";
}
// Update the new path to the user in the directory.
_path = result.Path;
_filterAttribute = (string)result.Properties["cn"][0];
}
catch (Exception ex)
{
s="Error authenticating user. " + ex.Message;
}
from the above code what the function of following statement is?
object obj = myLdapconnection.NativeObject;
Is this the statement to enable vpn?
if I add user to group then will he can use vpn connection?
Since obj is not used in the above code; it has no function and has nothing to do with VPN.
The code seems like it is trying to verify that a user exists, BUT it is weird.

WMI invalid Class error (trying to uninstall a software on remote pc)

All,
I am trying to uninstall a software remotely, it is working fine in the test machines, but i got problem in production servers.
test machines i have used windows xp, windows 2003 server,
production machine : windows server 2003.
what could be the cause of this error, any help would be more appreciated.
if you have any other way to unistall a software on the remote PC, please share.
public void Uninstallwithguid(string targetServer, string product,string guid, string version)
{
this.Project.Log(Level.Info, "Starting Uninstall " );
this.Project.Log(Level.Info, "targetServer :" + targetServer );
this.Project.Log(Level.Info, "product :" + product );
this.Project.Log(Level.Info, "guid :" + guid );
this.Project.Log(Level.Info, "version :" + version );
System.Management.ConnectionOptions connoptions = new System.Management.ConnectionOptions();
connoptions.Impersonation = System.Management.ImpersonationLevel.Impersonate;
connoptions.Timeout = new TimeSpan(0, 0, 10); // 10 seconds
System.Management.ManagementScope scope = new System.Management.ManagementScope(#"\\" + targetServer + #"\root\cimv2", connoptions);
scope.Connect();
System.Management.ObjectGetOptions objoptions = new System.Management.ObjectGetOptions();
string test = #"\\" + targetServer + #"\root\cimv2";
string objPath = string.Format("Win32_Product.IdentifyingNumber='{0}',Name='{1}',Version='{2}'",guid, product, version);
System.Management.ManagementPath path = new System.Management.ManagementPath(objPath);
System.Management.ManagementObject moobj = new System.Management.ManagementObject(scope, path, null);
UInt32 res1 = 0;
try
{
res1 = (UInt32)moobj.InvokeMethod("Uninstall", null);
}
catch(Exception ex)
{
this.Project.Log(Level.Error, ex.ToString());
throw ex;
}
if (res1 != 0)
{
this.Project.Log(Level.Error, "Uninstall error " + res1.ToString());
throw new Exception("Uninstall error " + res1.ToString());
}
}
Error Description :
System.Management.ManagementException: Invalid class
at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementObject.Initialize(Boolean getObject)
at System.Management.ManagementObject.get_ClassPath()
at System.Management.ManagementObject.GetMethodParameters(String methodName, ManagementBaseObject& inParameters, IWbemClassObjectFreeThreaded& inParametersClass, IWbemClassObjectFreeThreaded& outParametersClass)
at System.Management.ManagementObject.InvokeMethod(String methodName, Object[] args)
Win2003 doesn't have this class installed by default - you have to install it manually from the product disc.

Categories