老爷子88 发表于 2018-9-2 13:29:50

域环境通过powershell 远程修改本地管理员账户密码

function Invoke-PasswordRoll  
{
  

  
   
  
    Param(
  
      
  
      ]
  
      $ComputerName,
  

  
      
  
      ]
  
      $LocalAccounts,
  

  
      
  
      
  
      $TsvFileName,
  

  
      
  
      
  
      $EncryptionKey,
  

  
      
  
      
  
      
  
      $PasswordLength = 20,
  

  
      
  
      
  
      $NoEncryption
  
    )
  

  

  
#加载任何所需的 .net 类
  
    Add-Type -AssemblyName "System.Web" -ErrorAction Stop
  

  

  
#这是脚本块,将在 ComputerName 中指定的每台计算机上执行
  
    $RemoteRollScript = {
  
      Param(
  
            
  
            ]
  
            $Passwords,
  

  
            
  
            ]
  
            $LocalAccounts,
  

  
#在此处,我可以记录脚本所连接到的服务器名称,DNS 记录有时会变得很混乱,现在这样非常好。
  
            
  
            
  
            $TargettedServerName
  
      )
  

  
      $LocalUsers = Get-WmiObject Win32_UserAccount -Filter "LocalAccount=true" | Foreach {$_.Name}
  

  
#检查计算机是否具有密码不会由此脚本滚动的任何本地用户帐户
  
      foreach ($User in $LocalUsers)
  
      {
  
            if ($LocalAccounts -inotcontains $User)
  
            {
  
                Write-Warning "Server: '$($TargettedServerName)' has a local account '$($User)' whos password is NOT being changed by this script"
  
            }
  
      }
  

  
#对于此服务器中存在的所有指定的本地帐户,更改密码
  
      $PasswordIndex = 0
  
      foreach ($LocalAdmin in $LocalAccounts)
  
      {
  
            $Password = $Passwords[$PasswordIndex]
  

  
            if ($LocalUsers -icontains $LocalAdmin)
  
            {
  
                try
  
                {
  
                  $objUser = "WinNT://localhost/$($LocalAdmin), user"
  
                  $objUser.psbase.Invoke("SetPassword", $Password)
  

  
                  $Properties = @{
  
                        TargettedServerName = $TargettedServerName
  
                        Username =$LocalAdmin
  
                        Password = $Password
  
                        RealServerName = $env:computername
  
                  }
  

  
                  $ReturnData = New-Object PSObject -Property $Properties
  
                  Write-Output $ReturnData
  
                }
  
                catch
  
                {
  
                  Write-Error "Error changing password for user:$($LocalAdmin) on server:$($TargettedServerName)"
  
                }
  
            }
  

  
            $PasswordIndex++
  
      }
  
    }
  

  

  
#在运行此脚本的客户端上生成密码,而非在远程计算机上。.NET 客户端配置文件中不提供 System.Web.Security。在运行该脚本的 # 客户端上进行此调用可确保只有 1 台计算机需要安装完整的 .NET 运行库(相对于已滚动密码的每个系统)。
  
    function Create-RandomPassword
  
    {
  
      Param(
  
            
  
            
  
            
  
            $PasswordLength
  
      )
  

  
      $Password = ::GeneratePassword($PasswordLength, $PasswordLength / 4)
  

  
#此操作绝对不会失败,但不管怎样,我还是在这里加入了健全性检查
  
      if ($Password.Length -ne $PasswordLength)
  
      {
  
            throw new Exception("Password returned by GeneratePassword is not the same length as required. Required length: $($PasswordLength). Generated length: $($Password.Length)")
  
      }
  

  
      return $Password
  
    }
  

  

  
#主要功能 - 生成密码并通过远程方式进入计算机以更改指定的本地帐户的密码
  
    if ($PsCmdlet.ParameterSetName -ieq "Encryption")
  
    {
  
      try
  
      {
  
            $Sha256 = new-object System.Security.Cryptography.SHA256CryptoServiceProvider
  
            $SecureStringKey = $Sha256.ComputeHash(::Unicode.GetBytes($EncryptionKey))
  
      }
  
      catch
  
      {
  
            Write-Error "Error creating TSV encryption key" -ErrorAction Stop
  
      }
  
    }
  

  
    foreach ($Computer in $ComputerName)
  
    {
  
#需要为每个帐户生成 1 个可以更改的密码
  
      $Passwords = @()
  
      for ($i = 0; $i -lt $LocalAccounts.Length; $i++)
  
      {
  
            $Passwords += Create-RandomPassword -PasswordLength $PasswordLength
  
      }
  

  
      Write-Output "Connecting to server '$($Computer)' to roll specified local admin passwords"
  
      $Result = Invoke-Command -ScriptBlock $RemoteRollScript -ArgumentList @($Passwords, $LocalAccounts, $Computer) -ComputerName $Computer
  
#如果正在使用加密,则在写入磁盘之前,使用用户提供的密钥对密码进行加密
  
      if ($Result -ne $null)
  
      {
  
            if ($PsCmdlet.ParameterSetName -ieq "NoEncryption")
  
            {
  
                $Result | Select-Object Username,Password,TargettedServerName,RealServerName | Export-Csv -Append -Path $TsvFileName -NoTypeInformation
  
            }
  
            else
  
            {
  
#筛选掉返回的 $null 条目
  
                $Result = $Result | Select-Object Username,Password,TargettedServerName,RealServerName
  

  
                foreach ($Record in $Result)
  
                {
  
                  $PasswordSecureString = ConvertTo-SecureString -AsPlainText -Force -String ($Record.Password)
  
                  $Record | Add-Member -MemberType NoteProperty -Name EncryptedPassword -Value (ConvertFrom-SecureString -Key $SecureStringKey -SecureString $PasswordSecureString)
  
                  $Record.PSObject.Properties.Remove("Password")
  
                  $Record | Select-Object Username,EncryptedPassword,TargettedServerName,RealServerName | Export-Csv -Append -Path $TsvFileName -NoTypeInformation
  
                }
  
            }
  
      }
  
    }
  
}function ConvertTo-CleartextPassword
  
{
  
页: [1]
查看完整版本: 域环境通过powershell 远程修改本地管理员账户密码