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

本文关键字:代码 转换 PowerShell 帮助 | 更新日期: 2023-09-27 18:31:37

所以我有这个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 对象。

如果您可以发布有关如何执行此操作的示例,那将非常有帮助。我已经阅读了使用 C# 远程更改 Windows Server 2008 计算机的计算机名称?主题。它抛出的异常可能是因为它的这一行:

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 不可用。(异常结果:0x800706BA)这里:

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

新增2:

好的,我想我找到了导致错误的原因。

我已将原始 conn 用户名从

Username = oldName + "''" + accountWithPermissions.UserName,

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

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

那么如果我使用域''用户,

我应该在远程控制对象中更改命名空间路径以便能够使用域用户身份验证,这有什么问题?

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

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

因此,当服务器 RPC 不可用时,我通过使用 NETDOM 解决了这个问题。(异常结果: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 不可用。(异常结果:0x800706BA)发生不是因为我对脚本的更改。此错误如果仅由少数PC触发,因为我发现在许多情况下可能会发生更多关于此的信息: 获取WMI对象 :RPC服务器不可用。(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();
        }
    }