powershell 设置变量未正确传递
powershell Set-variable not passing properly
我在我的脚本中添加了一个菜单部分,它使用一个函数来设置变量以连接到 vcenter 服务器。问题是它没有传递变量。当我退出脚本时,当我执行 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
当它失败时,看起来变量没有被传递,它使用的是文字 $variable 而不是函数中设置的变量。 Get-variable returns 正确的变量(write-host $sourceVC 等也是如此)。这是错误:
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
该脚本在服务器的手动输入下工作正常,但由于操作将是 运行 脚本,我想排除手动错误,因为源和目标 vCenter 是已知的。
谢谢!
我建议使用 ([ref]$Variable).Value='NewValue'
来更新定义范围内的变量。
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
}
当通过按 F5 从 ISE 中 运行 此脚本时,ISE 实际上会 运行 全局范围内的脚本内容,就好像您要将代码复制并粘贴到控制台。这将:
- 清除全局范围内的 vCenter 变量。
- 这些函数将在全局范围内更新 vCenter 变量
- Connect-VIServer 将在全局范围内使用 $SourceVC 变量
另一方面,如果脚本是通过使用绝对或相对路径从控制台 运行 获得的,则代码将 运行 在它自己的范围内。此范围称为脚本范围,这将:
- 清除脚本范围内的 vCenter 变量
- 这些函数将更新全局范围内的 vCenter 变量
- Connect-VIServer 将在脚本中使用 $SourceVC 变量,该变量仍设置为 $null。
有两种解决方法:
- 使用so-called "dot-sourcing" 运行 控制台全局范围内的脚本内容。这是通过在脚本路径前添加一个点(句点)来完成的。例如:
. .\myscript.ps1
- 通过将 Set-Variable 的范围参数从 -Scope Global 更改为 -Scope Script 来让函数修改脚本范围中的变量,或者通过添加范围访问全局范围中的 $SourceVC 变量像这样的修饰符:
Connect-VIServer $Global:SourceVC
您可以在帮助文档中阅读有关范围的更多信息 about_Scopes。
我在我的脚本中添加了一个菜单部分,它使用一个函数来设置变量以连接到 vcenter 服务器。问题是它没有传递变量。当我退出脚本时,当我执行 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
当它失败时,看起来变量没有被传递,它使用的是文字 $variable 而不是函数中设置的变量。 Get-variable returns 正确的变量(write-host $sourceVC 等也是如此)。这是错误:
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
该脚本在服务器的手动输入下工作正常,但由于操作将是 运行 脚本,我想排除手动错误,因为源和目标 vCenter 是已知的。
谢谢!
我建议使用 ([ref]$Variable).Value='NewValue'
来更新定义范围内的变量。
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
}
当通过按 F5 从 ISE 中 运行 此脚本时,ISE 实际上会 运行 全局范围内的脚本内容,就好像您要将代码复制并粘贴到控制台。这将:
- 清除全局范围内的 vCenter 变量。
- 这些函数将在全局范围内更新 vCenter 变量
- Connect-VIServer 将在全局范围内使用 $SourceVC 变量
另一方面,如果脚本是通过使用绝对或相对路径从控制台 运行 获得的,则代码将 运行 在它自己的范围内。此范围称为脚本范围,这将:
- 清除脚本范围内的 vCenter 变量
- 这些函数将更新全局范围内的 vCenter 变量
- Connect-VIServer 将在脚本中使用 $SourceVC 变量,该变量仍设置为 $null。
有两种解决方法:
- 使用so-called "dot-sourcing" 运行 控制台全局范围内的脚本内容。这是通过在脚本路径前添加一个点(句点)来完成的。例如:
. .\myscript.ps1
- 通过将 Set-Variable 的范围参数从 -Scope Global 更改为 -Scope Script 来让函数修改脚本范围中的变量,或者通过添加范围访问全局范围中的 $SourceVC 变量像这样的修饰符:
Connect-VIServer $Global:SourceVC
您可以在帮助文档中阅读有关范围的更多信息 about_Scopes。