Reputation: 491
I wrote PowerShell script to automate some of the AD commands. Here is the script.
$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
I have tried to write-host the inputs and found $ValidatedHostServers array does not coming as array. May I be I am missing something in syntax.
There are two values in array but
Write-Host $ValidatedHostServers.Count display as 1.
Thanks in advance for helping here.
This is Error displayed in 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
Upvotes: 1
Views: 397
Reputation: 10170
If you reduce your code to a minimum script that reproduces the behaviour you'll get something like this:
$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)'";
which outputs the following:
value before = '"xxx"'
inside before = '"xxx"'
inside after = '"smp001-01sl1ps01-13-9"'
value after = '"xxx"'
I think there's two things happening here:
items that you create and change in the child scope do not affect the parent scope, unless you explicitly specify the scope when you create the items.
You can work around both of these issues like this:
#$ValidatedHostServers = @( "xxx" ); <- replace this with the next line
Set-Variable -Name "ValidatedHostServers" -Option AllScope -Value @( "xxx" );
The "AllScope" option allows the child scope (i.e. the function) to modify variables in the parent scope so your changes will persist after the function exists. It also side-steps the potential bug in the "assignment by addition operator".
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)'";
and then we get this output
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"
]'
UPDATE
Related issues in PowerShell github repo:
Upvotes: 2
Reputation: 3923
Try it this way, get the list then iterate over it:
function ValidateHost{
Param($HostServers)
#
$GroupName = Get-ADGroup -Identity $computerrole
#
# Get server validation list
$CheckedServers = $HostServers | ForEach-Object {
Try {
$HostOutput = Get-ADComputer -Identity $_ -ErrorAction Stop
$Validated = $true
}
Catch {
$Validated = $false
}
[pscustomobject]@{HostName = $_;Validated = $Validated}
}
# Add-HostComputer
# Iterate over list of validated servers
$CheckedServers | Where-Object { $_.Validated -eq $true } | ForEach-Object {
Try {
$DistinguishedName = Get-ADComputer -Identity $_.HostName -ErrorAction Stop
$Output = Add-ADGroupMember -Identity $GroupName -Members $DistinguishedName -Credential $Cred -ErrorAction Stop
}
Catch {
$Output = $_
}
[pscustomobject]@{HostName = $_.HostName;DN = $DistinguishedName;Result = $output}
}
}
Upvotes: 0