首页 > 解决方案 > 在 PowerShell 脚本中处理数组

问题描述

我编写了 PowerShell 脚本来自动化一些 AD 命令。这是脚本。

 $usergroup="TACACS Admins"
 $computerrole="1626-APPCONF"
 $zone="AWS"
 $username="<>"
 $password="<>";
 [String[]] $HostServers ='smp001-01','sl1ps01-13-9';

 $ValidatedHostServers = @()
 $NotValidatedHostServers = @()

 Import-Module ActiveDirectory
 Import-Module Centrify.DirectControl.PowerShell

 $Password = ConvertTo-SecureString $password -AsPlainText -Force
 $Cred = New-Object     System.Management.Automation.PSCredential($username,$Password)
Set-CdmCredential -Domain <> -Credential $Cred



function Add-HostComputer{
Param($cred,$zone,$computerrole,$ValidatedHostServers)

# Get Computer Role
$GroupName = Get-ADGroup -Identity $computerrole 
Write-Output $GroupName

foreach($Host in $ValidatedHostServers)
{
  #Get -Member 
  $DistinguishedName = Get-ADComputer -Identity $Host
  Write-Output $ValidatedHostServers

  #Add $Hostserver to $comprole computer Role
  $Output = Add-ADGroupMember -Identity $GroupName -Members $DistinguishedName -Credential $Cred
}
}



function ValidateHost{
  Param($HostServers)
  foreach($HostName in $HostServers)
 {
 try{
      $HostOutput = Get-ADComputer -Identity $HostName -ErrorAction SilentlyContinue
     $ValidatedHostServers += $HostName
 }
catch
{
    $NotValidatedHostServers += $HostName
}
}

 Write-Host $ValidatedHostServers
 $Result = @{"Valid_hosts"=$ValidatedHostServers;"Invalid_hosts"=$NotValidatedHostServers} | ConvertTo-Json -Compress
 Write-Host $Result
 Write-Host $ValidatedHostServers.Count
 If($ValidatedHostServers.Count -ne 0) 
  { 
  Write-Host $ValidatedHostServers
  Add-HostComputer -Cred $Cred -zone $zone -computerrole $computerrole - 
  ValidatedHostServers $ValidatedHostServers

  }

}
 $Final = ValidateHost -HostServers $HostServers
 Write-Host $Final

我试图写托管输入,发现 $ValidatedHostServers 数组不是作为数组出现的。可能我在语法上遗漏了一些东西。

数组中有两个值,但是

       Write-Host $ValidatedHostServers.Count display as 1.

在此先感谢您的帮助。

这是 powerShell 中显示的错误

  smp001-01sl1ps01-13-9
  {"Invalid_hosts":[],"Valid_hosts":"smp001-01sl1ps01-13-9"}
  1
  smp001-01sl1ps01-13-9
   Cannot overwrite variable Host because it is read-only or constant.
   At line:27 char:9 + foreach($Host in $ValidatedHostServers) + CategoryInfo : WriteError: (Host:String) [],      SessionStateUnauthorizedAccessException + FullyQualifiedErrorId : VariableNotWritable

 CN=1626-APPCONF,OU=Role Groups- 
 Computer,OU=Centrify,OU=Operations,DC=qateradatacloud,DC=com

标签: powershellpowershell-2.0

解决方案


如果您将代码减少到重现该行为的最小脚本,您将得到如下内容:

$ValidatedHostServers = @( "xxx" );

function ValidateHost
{
    write-host "inside before = '$($ValidatedHostServers | ConvertTo-Json)'";
    $ValidatedHostServers += "smp001-01";
    $ValidatedHostServers += "sl1ps01-13-9";
    write-host "inside after = '$($ValidatedHostServers | ConvertTo-Json)'";
    write-host ($ValidatedHostServers | ConvertTo-Json)
}

write-host "value before = '$($ValidatedHostServers | ConvertTo-Json)'";
ValidateHost;
write-host "value after = '$($ValidatedHostServers | ConvertTo-Json)'";

输出以下内容:

value before = '"xxx"'
inside before = '"xxx"'
inside after = '"smp001-01sl1ps01-13-9"'
value after = '"xxx"'

我认为这里发生了两件事:

  • 您的函数在子作用域中执行,因此在函数内部对父作用域中定义的变量(即 $ValidatedHostServer)所做的更改在函数退出时不会继续存在 - 请参阅子作用域链接的引用:

您在子范围中创建和更改的项目不会影响父范围,除非您在创建项目时明确指定范围。

  • 当 PowerShell 第一次将值分配给子范围中的父变量时,PowerShell 在通过加法运算符(即“+=”)进行赋值时可能存在错误 - 它基本上将 $ValidatedHostServers 视为未定义并将其转换为字符串,然后导致第二个 += 进行字符串连接而不是数组追加。

您可以像这样解决这两个问题:

#$ValidatedHostServers = @( "xxx" ); <- replace this with the next line

Set-Variable -Name "ValidatedHostServers" -Option AllScope -Value @( "xxx" );

“AllScope”选项允许子作用域(即函数)修改父作用域中的变量,因此您的更改将在函数存在后持续存在。它还回避了“加法运算符赋值”中的潜在错误。

Set-Variable -Name "ValidatedHostServers" -Option AllScope -Value @( "xxx" );

function ValidateHost
{
    write-host "inside before = '$($ValidatedHostServers | ConvertTo-Json)'";
    $ValidatedHostServers += "smp001-01";
    $ValidatedHostServers += "sl1ps01-13-9";
    write-host "inside after = '$($ValidatedHostServers | ConvertTo-Json)'";
    write-host ($ValidatedHostServers | ConvertTo-Json)
}

write-host "value before = '$($ValidatedHostServers | ConvertTo-Json)'";
ValidateHost;
write-host "value after = '$($ValidatedHostServers | ConvertTo-Json)'";

然后我们得到这个输出

value before = '"xxx"'
inside before = '"xxx"'
inside after = '[
    "xxx",
    "smp001-01",
    "sl1ps01-13-9"
]'
[
    "xxx",
    "smp001-01",
    "sl1ps01-13-9"
]
value after = '[
    "xxx",
    "smp001-01",
    "sl1ps01-13-9"
]'

更新

PowerShell github repo 中的相关问题:


推荐阅读