需要帮助将PowerShell转换为C#代码

时间:2014-11-24 10:20:17

标签: c# powershell

所以我有这个powershell代码:

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 = $_
}

我试图将其转换为C#并且无法找到实现此目的的方法。我只是不了解如何创建WMI对象。

如果您可以发布和示例如何执行此操作,将会非常有帮助。 我已经阅读了这个Remotely change computer name for a Windows Server 2008 machine using C#?主题。并且由于这一行而引发异常可能是:

Authentication = AuthenticationLevel.PacketPrivacy

我使用的是System.Net.Security命名空间,正如评论中所述,PacketPrivacy只存在于那里。

由于我的评价很低,我不能在那里问我,我再次问过。

如果有人能帮助我,我将不胜感激。

PS:我知道这可以使用NETDOM完成,但我更喜欢使用WMI对象。

增加:

我试图使用它:

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

我收到此错误服务器RPC不可用。 (Exception HRESULT:0x800706BA)这里:

ManagementBaseObject newRemoteSystemName = remoteSystem.GetMethodParameters("Rename");

ADDED2:

好的,我想我发现了导致错误的原因。

我已从

更改原始 conn 用户名
Username = oldName + "\\" + accountWithPermissions.UserName,

Username = accountWithPermissions.Domain + "\\" + accountWithPermissions.UserName,

并且发生错误,如果我使用旧代码,我会获得ACCESS_IS_DENIED并且这是正确的,因为该用户没有权利。

如果我使用Domain \ User会出现什么问题?我可能应该更改 remoteControlObject 中的 NamespacePath 以便能够使用域用户身份验证吗?

1 个答案:

答案 0 :(得分:0)

我无法找到解决此问题的方法,似乎没有人有答案。

服务器RPC不可用时,我已使用 NETDOM 解决了这个问题。 (Exception HRESULT:0x800706BA)实际上发生了任何错误我将添加拒绝访问权限检查,以便在发生这种情况时不会尝试使用NETDOM;

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

服务器RPC不可用。 (异常HRESULT:0x800706BA)正在发生,不是因为我对脚本的更改。这个错误如果只是由少数几家PC发起,我发现在很多情况下可能会发生这种错误:Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)。更改远程PC上的设置使我可以直接从该PC检查设置。在那种情况下,我可以重命名PC甚至不试图找出这发生了什么。这就是我使用 NETDOM 的原因,因为出于某种原因,远程重命名该PC并没有问题。

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

    }