powershell Set-variable未正确传递

时间:2015-12-28 19:33:33

标签: powershell powercli

我添加了我的脚本的菜单部分,该部分使用函数来设置变量以连接到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

当它失败时,看起来变量没有被传递,它使用文字$变量而不是函数中设置的变量。 Get-variable返回正确的变量(write-host $ sourceVC等也是如此)。这是错误:

  

Connect-VIServer:无法验证参数'Server'的参数。该   参数为null或空。提供非null或的参数   空,然后再次尝试命令。

     

在D:\ scripts \ vm-uscmigration.ps1:84 char:18

     

+ connect-viserver $ SourceVC   + ~~~~~~~~~ CategoryInfo:InvalidData :( :) [Connect-VIServer],ParameterBindingValidationException   + FullyQualifiedErrorId:ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.ConnectVIServer

该脚本在服务器的手动输入下工作正常,但由于Operations将运行脚本,因此我希望手动错误不在等式中,因为源和目标vCenters是已知的。

谢谢!

2 个答案:

答案 0 :(得分:1)

我建议使用([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
}

答案 1 :(得分:0)

当通过按F5从ISE中运行此脚本时,ISE将实际运行全局范围内的脚本内容,就像您要在控制台中复制并粘贴代码一样。这将:

  • 清除全局范围内的vCenter变量。
  • 这些功能将更新全局范围内的vCenter变量
  • Connect-VIServer将使用全局范围内的$ SourceVC变量

另一方面,如果使用绝对路径或相对路径从控制台运行脚本,则代码将在其自己的范围内运行。此范围称为脚本范围,它将:

  • 清除脚本范围中的vCenter变量
  • 这些功能将更新全局范围内的vCenter变量
  • Connect-VIServer将在脚本中使用$ SourceVC变量,该变量仍设置为$ null。

有两种解决方法:

  1. 使用所谓的“dot-sourcing”在控制台的全局范围内运行脚本的内容。这是通过在脚本路径之前添加一个点(句点)来完成的。例如:
  2. . .\myscript.ps1

    1. 要么让函数通过将-Scope Global的Set-Variable的scope参数更改为-Scope Script来修改脚本范围中的变量,要么通过添加如下的范围修饰符来访问全局范围中的$ SourceVC变量:
    2. Connect-VIServer $Global:SourceVC

      您可以在帮助文档about_Scopes中阅读有关范围的更多信息。