I added a menu portion of my script which is using a function to set-variables for connections to vcenter servers. The problem is it isn't passing the variable. When I quit the script the variable is correct when I do a get-variable.
#Main menu
function MainMenu {
Clear-Host
[int]$xMenuChoiceA = 0
while ($xMenuChoiceA -lt 01 -or $xMenuChoiceA -gt 04) {
Write-Host "============================================" -ForegroundColor Green
Write-Host "| Main Menu |" -ForegroundColor Green
Write-Host "============================================" -ForegroundColor Green
Write-Host "| Migration Script |" -ForegroundColor Green
Write-Host "============================================" -ForegroundColor Green
Write-Host "| |" -ForegroundColor Green
Write-Host "| 1. Development |" -ForegroundColor Green
Write-Host "| 2. Model |" -ForegroundColor Green
Write-Host "| 3. Production |" -ForegroundColor Green
Write-Host "| 4. Quit |" -ForegroundColor Green
Write-Host "| |" -ForegroundColor Green
Write-Host "============================================" -ForegroundColor Green
Write-Host ""
Write-Host "Please enter an option 1 to 4..." -ForegroundColor Green -NoNewline
[Int]$xMenuChoiceA = Read-Host
}
Switch($xMenuChoiceA) {
1 { SetDev }
2 { SetModel }
3 { SetProd }
4 { Are-YouSure }
default { MainMenu }
}
}
#Verifiyng exit of menu
function Are-YouSure {
Write-Host "Are you sure you want to exit? (y/n)" -ForegroundColor Cyan -NoNewline
$areyousure = Read-Host
if ($areyousure -eq "y") { exit }
if ($areyousure -eq "n") { MainMenu }
else {
Write-Host -ForegroundColor Red "Invalid Selection"
Are-YouSure
}
}
#clear vCenter variables
$SourceVC = $null
$DestVC = $null
#menu set vCenter function
function SetDev {
Set-Variable -Name SourceVC -Value devvc.effingps.corp -Scope global
Set-Variable -Name DestVC -Value ucsvcd.effingps.corp -Scope global
break
}
function SetModel {
Set-Variable -Name SourceVC -Value modelvc.effingps.corp -Scope global
Set-Variable -Name DestVC -Value ucsvcm.effingps.corp -Scope global
break
}
function SetProd {
Set-Variable -Name SourceVC -Value prodvc.effingps.corp -Scope global
Set-Variable -Name DestVC -Value ucsvcp.effingps.corp -Scope global
break
}
MainMenu
#connects to the source vCenter for right-sizing
Connect-VIServer $SourceVC
When it fails it looks like the variable is not passed and it's using the literal $variable instead of the variable that was set in the function. Get-variable returns the correct variable (as does write-host $sourceVC, etc). Here's the error:
Connect-VIServer : Cannot validate argument on parameter 'Server'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At D:\scripts\vm-uscmigration.ps1:84 char:18
+ connect-viserver $SourceVC + ~~~~~~~~~ CategoryInfo : InvalidData: (:) [Connect-VIServer], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.ConnectVIServer
The script did work fine with manual input for the servers, but as Operations will be running the script, I wanted to take manual error out of the equation since the source and destination vCenters are known.
Thanks!
I suggest to use ([ref]$Variable).Value='NewValue'
to update variable in the scope where it defined.
function SetDev {
([ref]$SourceVC).Value='devvc.effingps.corp'
([ref]$DestVC).Value='ucsvcd.effingps.corp'
break
}
function SetModel {
([ref]$SourceVC).Value='modelvc.effingps.corp'
([ref]$DestVC).Value='ucsvcm.effingps.corp'
break
}
function SetProd {
([ref]$SourceVC).Value='prodvc.effingps.corp'
([ref]$DestVC).Value='ucsvcp.effingps.corp'
break
}