PowerShell-If-Then:无法对空值表达式调用方法



当我运行这个函数所在的程序时,我收到了一个对我来说没有意义的神秘错误。我不知道我在空值表达式上运行了一个方法。我突然想到,这要么是范围问题,要么是没有设置值。然而,我还没能弄清楚并向社区发布:

You cannot call a method on a null-valued expression.
At C:UsersAdministratorDesktopDCB Settings ModificationDCBxPowershell.ps1:747 char:21
+                 If ($resetAdapter -eq $FAIL_RESULT){
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:UsersAdministratorDesktopDCB Settings ModificationDCBxPowershell.ps1:760 char:17
+             If ($resetAdapter -eq $FAIL_RESULT){
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull**

$FAIL_RESULT = 0
$PASS_RESULT = 1
Function Use-Menu
{ 
    param($DCBmenuItems, $modificationCatagoryChoosen)
    ## Function Menu-Choose --## Holds choosen Network Interface Index to work with            
    $networkIndex = Menu-Choose $strippedNetworkIndex $networkChooseTitle
    #$networkIndex[0]  ### Debug -
    $resetAdapter = $FAIL_RESULT
    Start-Sleep -s .7
    If ($result = $PASS_RESULT) {
    ## Find Current Config in order to display it to user
        $dcbConfig = Find-Config $networkIndex
    }
    #The following 'DO WHILEs' are for the "Go back to previous Menu" functionality.
    Do {
        Do {
            ## Function Menu-Choose --## Let user choose which catagory of modification to perform
            $modificationCatagoryChoosen = Menu-Choose $DCBmenuItems $DCBMenuTitle $networkIndex -scope global
            If (($DCBmenuItems.count - 1) -eq $modificationCatagoryChoosen) {
                $resetAdapter = $PASS_RESULT
            }
            # These If Then statements allow reset of adapter without changing settings
            If ($resetAdapter -eq $FAIL_RESULT){
                $DCBmenuItems2 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].Option
                $DCBMenuTitle2 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].Name
                Start-Sleep -s .7
                ## Function Menu-Choose --## Let user choose which modification to perform
                $modificationChoosen = Menu-Choose $DCBmenuItems2 $DCBMenuTitle2 $networkIndex
            }
        } While (($modificationChoosen -eq $DCBmenuItems2.GetUpperBound(0)) -and ($resetAdapter -eq $FAIL_RESULT))
        # These If Then statements allow reset of adapter without changing settings
        If ($resetAdapter -eq $FAIL_RESULT){ 
            ## Changes the options to choose on Menu-Choose to last chosen catagory
            $DCBmenuItems3 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].SubMenu[$modificationChoosen].Option
            $DCBMenuTitle3 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].SubMenu[$modificationChoosen].Name
            Start-Sleep -s .7
            ## Function Menu-Choose --## Let user choose how to modify DCB setting
            $modificationOptionChoosen = Menu-Choose $DCBmenuItems3 $DCBMenuTitle3 $networkIndex
        }
    } While (($modificationOptionChoosen -eq $DCBmenuItems3.GetUpperBound(0)) -and ($resetAdapter -eq $FAIL_RESULT)) 
    # These If Then statements allow reset of adapter without changing settings
    If ($resetAdapter -eq $FAIL_RESULT){
        Start-Sleep -s .7
         ## Function Set-RegistryValues --## Records modified DCB setting to registry
        Set-RegistryValues $xmlDCBregEdits $modificationCatagoryChoosen $modificationChoosen $modificationOptionChoosen
    }
Return $networkIndex

从最初的两个if-then语句改为在我的初始if-then声明后插入break,并在第二个Do循环中添加一个相同的语句,似乎解决了我的问题。我这样做的原因是,在进入菜单的一层,然后返回顶层后,我注意到在选择重置适配器时没有出现错误。

侧栏:我没有解释我在这里列出的函数是一个遍历$DCBmenuItems,尽管这可能从代码中已经很明显了。

我认为$resetAdapter由于某种原因没有正确设置。我不能100%确定为什么这解决了我的问题,以及为什么其他代码会抛出错误。这是修改后的代码:

$FAIL_RESULT = 0
$PASS_RESULT = 1
Function Use-Menu
{ 
    param($DCBmenuItems, $modificationCatagoryChoosen)
    ## Function Menu-Choose --## Holds choosen Network Interface Index to work with            
    $networkIndex = Menu-Choose $strippedNetworkIndex $networkChooseTitle
    #$networkIndex[0]  ### Debug -
    $resetAdapter = $FAIL_RESULT
    $modificationCatagoryChoosen = $null
    $modificationChoosen = $null
    $modificationOptionChoosen = $null
    $DCBmenuItems2 = $null
    $DCBMenuTitle2 = $null
    $DCBmenuItems3 = $null
    $DCBMenuTitle3 = $null
    Start-Sleep -s .7
    If ($result = $PASS_RESULT) {
    ## Find Current Config in order to display it to user
        $dcbConfig = Find-Config $networkIndex
    }
    #The following 'DO WHILEs' are for the "Go back to previous Menu" functionality.
    Do {
        Do {
            ## Function Menu-Choose --## Let user choose which catagory of modification to perform
            $modificationCatagoryChoosen = Menu-Choose $DCBmenuItems $DCBMenuTitle $networkIndex -scope global
            If (($DCBmenuItems.count - 1) -eq $modificationCatagoryChoosen) {
                $resetAdapter = $PASS_RESULT
                break
            }
            # These If Then statements allow reset of adapter without changing settings
            $DCBmenuItems2 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].Option
            $DCBMenuTitle2 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].Name
            Start-Sleep -s .7
            ## Function Menu-Choose --## Let user choose which modification to perform
            $modificationChoosen = Menu-Choose $DCBmenuItems2 $DCBMenuTitle2 $networkIndex

        } While (($modificationChoosen -eq $DCBmenuItems2.GetUpperBound(0)) -and ($resetAdapter -eq $FAIL_RESULT))
        If (($DCBmenuItems.count - 1) -eq $modificationCatagoryChoosen) {
                break
        }
        # These If Then statements allow reset of adapter without changing settings
        ## Changes the options to choose on Menu-Choose to last chosen catagory
        $DCBmenuItems3 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].SubMenu[$modificationChoosen].Option
        $DCBMenuTitle3 = $xmlDCBoptions.MenuItems.MenuOptions[$modificationCatagoryChoosen].SubMenu[$modificationChoosen].Name
        Start-Sleep -s .7
        ## Function Menu-Choose --## Let user choose how to modify DCB setting
        $modificationOptionChoosen = Menu-Choose $DCBmenuItems3 $DCBMenuTitle3 $networkIndex
    } While (($modificationOptionChoosen -eq $DCBmenuItems3.GetUpperBound(0)) -and ($resetAdapter -eq $FAIL_RESULT)) 
    # These If Then statements allow reset of adapter without changing settings
    If ($resetAdapter -eq $FAIL_RESULT){
        Start-Sleep -s .7
         ## Function Set-RegistryValues --## Records modified DCB setting to registry
        Set-RegistryValues $xmlDCBregEdits $modificationCatagoryChoosen $modificationChoosen $modificationOptionChoosen
    }
Return $networkIndex

}

此错误的位置似乎不正确。我看不出PowerShell是如何在if ()条件下得到这种类型的错误的。然而,这条线可能会导致错误:

$DCBmenuItems3.GetUpperBound(0)

添加一个检查以确保$DCBmenuItems3不为空。此外,当调试问题时(或者像正常做法一样检查),我会将Set-StrictMode -version latest放在脚本的顶部。

FAIL_RESULT = 0
PASS_RESULT = 1

打字错误?

$FAIL_RESULT = 0
$PASS_RESULT = 1

最新更新