Quick Overview: Script has two functions, one gets a two lists of roles and puts them in a hash table, then returns that hash table. Process-Roles then accepts a hash table, and does some comparisons on it.
$RoleTable is supposed to be a hash table, but I think after my Get-Roles function, Powershell makes the $RoleTable an object array. I then get a conversion error:
Cannot convert the "System.Object[]" value of type "System.Object[]" to type
"System.Collections.Hashtable".
Here's the "main" of my script
$creds = Get-Credential
$MasterServer = Read-Host "`n Master Server"
$SlaveServer = Read-Host "`n Slave Server"
$RoleTable = Get-Roles -MasterServer $MasterServer -SlaveServer $SlaveServer -Credential $creds
Process-Roles -RoleTable $RoleTable
Here's the function I make a hashtable in, and pass that to $RoleTable
function Get-Roles {
Param(
[Parameter(Mandatory=$True,Position=0)]
[string]$MasterServer,
[Parameter(Mandatory=$True,Position=1)]
[string]$SlaveServer,
[Parameter(Mandatory=$True,Position=2)]
[pscredential]$Credential
)
$DiscoveredRoles = @{}
# Get Master Roles
Connect-VIServer $MasterServer -Credential $Credential | out-null
$DiscoveredRoles["MasterRoles"] = Get-VIRole
Disconnect-VIServer $MasterServer -Confirm:$false
#Get Slave Roles
Connect-VIServer $SlaveServer -Credential $Credential | out-null
$DiscoveredRoles["SlaveRoles"] = Get-VIrole
Disconnect-VIServer $SlaveServer -Confirm:$false
Write-Verbose "`n + Retrieved Roles Successfully"
return $DiscoveredRoles
}
Here's where the error occurs. Process-Roles requires a hashtable, but I believe powershell converted $RoleTable to an array? (that's at least what my google-fu told me)
function Process-Roles {
param(
[Parameter(Mandatory=$true)]
[ValidateScript({ $_.ContainsKey("MasterRoles") -and $_.ContainsKey("SlaveRoles") })]
[hashtable]$RoleTable
)
$MasterRoleNames = $RoleTable["MasterRoles"] |Select-Object -ExpandProperty Name
$SlaveRoleNames = $RoleTable["SlaveRoles"] |Select-Object -ExpandProperty Name
$MasterRoleNames |Where-Object { $SlaveRoleNames -notcontains $_ } |ForEach-Object {
Write-Verbose "$_ doesn't exist on slave"
}
$SlaveRoleNames |Where-Object { $MasterRoleNames -notcontains $_ } |ForEach-Object {
Write-Verbose "$_ doesn't exist on Master"
}
Write-Verbose "`n + Processed Roles Successfully"
}
A PowerShell function returns an array when there are multiple values returned. Every statement in a function that returns a value that is not ignored and not assigned to a variable contributes to the return values.
I see that Connect-VIServer
returns something. Therefore the Get-Roles
will return multiple values: including two from the two calls to Connect-VIServer
.
If you do not want the values from these other statements you need to explicitly get rid of them. Eg. by piping into out-null
.
Eg. (thank's to @MathiasRJessen):
Connect-VIServer $SlaveServer -Credential $Credential | Out-Null