使用PowerShell一步重命名计算机并加入域

使用PowerShell一步重命名计算机并加入域,powershell,powershell-2.0,Powershell,Powershell 2.0,目标:在运行Windows Server 2008 R2的计算机上,使用PowerShell 2.0: 重命名计算机 将计算机加入域 条件:第1步和第2步必须同时执行,即两步之间不需要重新启动计算机 我正在使用的函数 这些是我为每个步骤创建的PowerShell函数 重命名计算机 根据我在互联网上的研究,PowerShell 2.0在发布前曾有一个内置cmdlet,名为重命名计算机,但由于CTP 3中未知的原因被删除。我的版本使用WMI function Rename-Computer {

目标:在运行Windows Server 2008 R2的计算机上,使用PowerShell 2.0:

  • 重命名计算机
  • 将计算机加入域
  • 条件:第1步和第2步必须同时执行,即两步之间不需要重新启动计算机

    我正在使用的函数 这些是我为每个步骤创建的PowerShell函数

    重命名计算机 根据我在互联网上的研究,PowerShell 2.0在发布前曾有一个内置cmdlet,名为重命名计算机,但由于CTP 3中未知的原因被删除。我的版本使用WMI

    function Rename-Computer
    {
        param ( [Parameter(Mandatory=$true)][string]$name )
    
        process
        {
            try
            {
                $computer = Get-WmiObject -Class Win32_ComputerSystem
                $result = $computer.Rename($name)
    
                switch($result.ReturnValue)
                {       
                    0 { Write-Host "Success" }
                    5 
                    {
                        Write-Error "You need administrative rights to execute this cmdlet" 
                        exit
                    }
                    default 
                    {
                        Write-Host "Error - return value of " $result.ReturnValue
                        exit
                    }
                }
            }
            catch
            {
                Write-Host "Exception occurred in Rename-Computer " $Error
            }
        }
    }
    
    将计算机加入域 如您所见,此函数实际上只是内置cmdletAdd Computer的包装器,它收集域名并创建一些要使用的凭据

    function Join-ComputerToDomain
    {
        param ( [Parameter(Mandatory=$true)][string]$domain )
    
        process
        {
            try
            {
                $_domainCredential = $Host.UI.PromptForCredential("Enter domain credentials", "Enter domain credentials to be used when joining computer to the domain", "", "NetBiosUserName")
                Add-Computer -DomainName $_domain -cred $_domainCredential
            }
            catch
            {
                Write-Error "Exception occurred in Join-ComputerToDomain " $Error
            }
        }
    }
    
    我试过的步骤 尝试1
  • 调用重命名计算机
  • 调用加入计算机域
  • 重新启动
  • 结果:重命名计算机的输出表明名称已更改,但重新启动后,名称未更改,但计算机已加入域

    尝试2
  • 调用加入计算机域
  • 调用重命名计算机
  • 重新启动
  • 结果:重命名计算机返回的值为1326(登录失败:未知用户名或错误密码)。我认为这是因为一旦加入域,重命名就需要域凭据。我试图在重命名计算机中使用Get-WmiObject调用的凭据,但它抛出了一个错误,即无法在本地系统上使用不同的凭据

    尝试3
  • 调用重命名计算机
  • 重新启动
  • 调用加入计算机域
  • 重新启动

  • 结果:一切正常,但需要额外重启。工作正常,但我想消除第2步的重启

    由于没有人回答,我尝试了一些方法:

    我想我明白了为什么一个人不工作。这是因为将一台计算机加入一个域某种程度上也会重命名该计算机(域名部分,输入计算机名称)


    所以,如果您尝试以完整的WMI方式执行此操作,那么您在
    Win32\u ComputerSystem
     名为
    JoinDomainOrWorkgroup
    的类。在同一级别上执行此操作可能会让您有更多的机会使其工作。

    重命名计算机已从CTP3中删除,因为重命名计算机时会执行很多操作,MS可能不想重新创建该过程,也可能无法包含所有必需的位。我想Jefferey Snover说过只使用netdom.exe,因为这是在命令行上重命名计算机的最佳实践。这不是您想要的答案,但应该为您指明正确的方向

    实际上,在重命名计算机后或加入域时(这与AD验证的操作基本相同),您必须重新启动的原因有很多。一个是在基于NT的计算机上(我相信这始于Windows 2000),应用程序和网络服务在启动时读取计算机名称。这是他们唯一一次读取计算机名,因此如果您在不重新启动的情况下重命名计算机,网络和应用程序服务将不会响应新的计算机名。当您首先重命名计算机,然后尝试加入域时,这一点尤为重要,因为如果网络堆栈没有响应正确的计算机名,kerberos握手就无法完成

    另一个原因是多个注册表项使用了计算机名,这些注册表项在加载到内存时无法更改(这也是为什么有些程序需要重新启动才能完成安装或卸载)

    您可以使用RunOnce注册表项(msdn.microsoft.com/en-us/library/aa376977%28v=vs.85%29.aspx)在重新启动时自动运行域加入脚本,但您仍然需要重新启动这两个操作

    如果您真的想变得棘手,可以在重命名脚本中添加一些代码,设置RunOnce注册表项,以便在重新启动时启动域加入脚本。但要注意,如果要执行此操作,将写入HKLM配置单元的脚本必须以管理员身份运行(如果已打开UAC,则尤为重要)

    如果您想这样做,您可以在重命名计算机功能的末尾使用如下内容:

    Set-Location -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce'
    Set-ItemProperty -Path . -Name joinDomain -Value "C:\scripts\joinDomain.ps1"
    Restart-Computer
    
    这将在RunOnce注册表项(假设您正在运行Vista/7/2008)中创建名为“joinDomain”的子项,其值为“C:\scripts\joinDomain.ps1”

    如果这对您不起作用,请尝试将第二行更改为:

    Set-ItemProperty -Path . -Name joinDomain -Value 'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe "C:\scripts\joinDomain.ps1"'
    

    如果您遇到问题,请告诉我。

    我可以使用以下方法通过一次重新启动完成这两项任务,并且它使用以下JoinDomainOrWorkGroup标志工作。这是一个使用Windows 2008 R2 Enterprise的新版本。我验证了它确实使用新名称在广告中创建了计算机帐户

    1(0x1) 违约将计算机加入域。如果未指定此值,则连接是计算机到工作组

    32(0x20) 允许加入新域,即使计算机已加入域

    $comp=gwmi win32_computersystem
    $cred=get-credential
    $newname="*newcomputername*"
    $domain="*domainname*"
    $OU="OU=Servers, DC=domain, DC=Domain, DC=com"
    $comp.JoinDomainOrWorkGroup($domain ,($cred.getnetworkcredential()).password, $cred.username, $OU, 33)
    $comp.rename($newname,$cred.getnetworkcredential()).password,$cred.username)
    

    我今天也在找同样的事情,终于找到了一个方法。我被暗示这是可能的,因为使用了sconfig,它会询问您在加入域后是否要更改计算机名。这是我的原始代码行。它可能会增强,但现在想起来会很累

    $strCompName = Read-host 'Name '
    $strAdmin = read-host "Authorized user for this operation "
    $strDomain = read-host "Name of the domain to be joined "
    add-computer -DomainName $strDomain -Credential $strAdmin
    Rename-computer -newname $strCompName -DomainCredential $strAdmin
    

    该解决方案正在发挥作用:

    • 在Active Directory域中输入具有身份验证的计算机(无需重新启动)
    • 使用身份验证重命名计算机(无需重新启动)
    • 之后,重新启动
    # get the credential 
    $cred = get-credential
    
    # enter the computer in the right place
    Add-Computer -DomainName EPFL -Credential $cred -OUPath "...,DC=epfl,DC=ch"
    
    # rename the computer with credential (because we are in the domain)
    $Computer = Get-WmiObject Win32_ComputerSystem
    $r = $Computer.Rename("NewComputerName", $cred.GetNetworkCredential().Password, $cred.Username)
    
    $oldName = Read-Host -Prompt "Enter Original Computer Name"
    $newName = Read-Host -Prompt "Enter New Computer Name"
    $domain = Read-Host -Prompt "Enter Domain Name to be added"
    $user = Read-Host -Prompt "Enter Domain user name"
    $password = Read-Host -Prompt "Enter password for $user" -AsSecureString 
    $username = "$domain\$user" 
    $credential = New-Object System.Management.Automation.PSCredential($username,$password) 
    Rename-Computer -NewName $newName -LocalCredential admin -Force
    Write-Host "Please waiting for a moment to change Domain and then restart" -ForegroundColor Red
    Add-Computer -ComputerName $oldName -DomainName $domain -Options JoinWithNewName -Credential $credential -Restart
    
    $userid="$DOMAIN\$USERNAME"
    $secure_string_pwd = convertto-securestring "SECRET_PASSWORD" -asplaintext -force
    $creds = New-Object System.Management.Automation.PSCredential $userid,$secure_string_pwd
    
    Rename-Computer "newhostname" -DomainCredential $creds -Force
    WARNING: The changes will take effect after you restart the computer OLDHOSTNAME.
    
    Add-Computer -NewName "newhostname" -DomainName $DOMAIN -Credential $creds \
    -OUPath "OU=MYORG,OU=MYSUBORG,DC=THEDOMAIN,DC=Net" -Force
    WARNING: The changes will take effect after you restart the computer OLDHOSTNAME.
    
    Restart-Computer
    
    $computerName = Get-WmiObject Win32_ComputerSystem 
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null 
    $name = [Microsoft.VisualBasic.Interaction]::InputBox("Enter Desired Computer Name ")
    $computername.rename("$name")
    Add-Computer -DomainName [domainname] -Credential [user\domain]  -Verbose
    Restart-Computer
    
    #Set A local admin account
    $computername = $env:computername   # place computername here for remote access
    $username = 'localadmin'
    $password = 'P@ssw0rd1'
    $desc = 'Local admin account'
    $computer = [ADSI]"WinNT://$computername,computer"
    $user = $computer.Create("user", $username)
    $user.SetPassword($password)
    $user.Setinfo()
    $user.description = $desc
    $user.setinfo()
    $user.UserFlags = 65536
    $user.SetInfo()
    $group = [ADSI]("WinNT://$computername/administrators,group")
    $group.add("WinNT://$username,user")
    
    # Set computer name 
    $computerName = Get-WmiObject Win32_ComputerSystem 
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null 
    $name = [Microsoft.VisualBasic.Interaction]::InputBox("Enter Desired Computer Name ")
    $computername.rename("$name")
    
    #Now Join to Domain
    Add-Computer -DomainName [domainname] -Credential [user\domain]  -Verbose
    Restart-Computer
    
    $servicetag = Get-WmiObject win32_bios | Select-Object -ExpandProperty SerialNumber
    Add-Computer -Credential DOMAIN\USER -DomainName DOMAIN -NewName $servicetag
    
    mydomain\admin
    
    mydomain.local
    
    Add-Computer -DomainName xxxx -ComputerName xxxx -NewName xxxx -Credential Domain\Admin -Restart
    
    Rename-Computer -NewName xxxx -Restart
    
    Add-Computer -DomainName xxxx -Credential xxxx\xxxxx -Restart
    
    $domain = "domain.local"
    $password = "Passw@rd" | ConvertTo-SecureString -asPlainText -Force
    $username = "$domain\Administrator"
    $hostname=hostname
    $credential = New-Object System.Management.Automation.PSCredential($username,$password)
    Add-Computer -DomainName $domain -ComputerName $hostname -NewName alrootca -Credential $credential -Restart
    
    $Chops = Get-Credential 
    # Or bring in a stored credential
    $NewComputerName = "WhoImGonnaBe" 
    # or value from CSV
    $MyDomainName = "MyDomain"
    Add-Computer -WorkgroupName NotADomain -force -DomainCredential $Chops
    Add-Computer -DomainName $MyDomainName -Computername $ENV:Computername -NewName $NewComputerName -DomainCredential $Chops -Force -Restart
    #  If running locally you really only need the -NewName and can omit the -Computername