【问题标题】:Trouble with Powershell functions in .ps1.ps1 中的 Powershell 函数存在问题
【发布时间】:2013-12-01 22:46:58
【问题描述】:

我正在尝试修改一个工作脚本,使其模块化。该脚本的目的是连接到 DPM 服务器、获取附加的库并清点它们。清点完成后,脚本会将相应的磁带标记为“空闲”。脚本如下

我有两个问题。第一个来了又走了,因为我已经编辑了脚本。当我运行脚本:.\script.ps1,Powershell 说:

C:\it\test.ps1:无法验证参数“DPMLibrary”上的参数。参数为空。提供一个非空参数并再次尝试该命令。

在 line:1 char:11 + .\test.ps1

  • CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1

第二个问题出现在我刚刚将函数复制到 shell 中时。 Get-Libraries 函数工作正常并返回连接库的属性。当我将参数传递给 Inventory-DPMLibrary 时,库存完成。当我将库参数传递给 Update-TapeStatus 函数时,我收到一条错误消息,提示

运算符 '-notmatch' 的参数错误:解析“slot” - 量词 {x,y} 跟随 无所事事..

在 line:6 char:77

  • $tapes = 获取-DPMTape -DPMLibrary $lib |其中 {$_.Location -不匹配
  • CategoryInfo : InvalidOperation: (:) [], RuntimeException ? + FullyQualifiedErrorId : BadOperatorArgument

看起来 $liblist 参数为空,即使变量不是。什么给了?

这是脚本:

[CmdletBinding()]
param(
    [ValidateSet("Fast","Full")]
    [string]$InventoryType = 'Fast',

    [string]$DPMServerName = 'server1'
)

Function Import-DPMModule {
    Try {
        Import-Module DataProtectionManager -ErrorAction Stop
    }
    Catch [System.IO.FileNotFoundException] {
        Throw ("The DPM Powershell module is not installed or is not importable. The specific error message is: {0}" -f $_.Exception.Message)
    }
    Catch {
        Throw ("Unknown error importing DPM powershell module. The specific error message is: {0}" -f $_.Exception.Message)
    }
}

Function Get-Libraries {
    Write-Verbose ("Getting list of libraries connected to {0}." -f $DPMServerName)
    Try { 
       $libraries = Get-DPMLibrary $DPMServerName -ErrorAction Stop | Where {$_.IsOffline -eq $False}
    }
    Catch [Microsoft.Internal.EnterpriseStorage.Dls.Utils.DlsException] {
        Write-Error ("Cannot connect to the DPM library. It appears that the servername is not valid. The specific error message is: {0}" -f $_.Exception.Message)
        Return
    }
    Catch {
        Write-Error ("Unknown error getting library. The specific error message is: {0}" -f $_.Exception.Message)
        Return
    }

    Return $libraries
}

Function Inventory-DPMLibraries ($liblist) {
    Foreach ($lib in $liblist) {
        If ($InventoryType -eq "Fast") {
            Write-Verbose ("Starting fast inventory on {0}" -f $lib)
            $inventoryStatus = Start-DPMLibraryInventory -DPMLibrary $lib -FastInventory -ErrorAction SilentlyContinue
        }
        Else {
            Write-Verbose ("Starting detailed inventory on {0}" -f $lib)
            $inventoryStatus = Start-DPMLibraryInventory -DPMLibrary $lib -DetailedInventory -ErrorAction SilentlyContinue
        }

        While ($inventoryStatus.HasCompleted -eq $False) {
            Write-Output ("Running {0} inventory on library: {1}" -f $InventoryType.ToLower(),$lib.UserFriendlyName)
            Start-Sleep 5
        }
        If ($inventoryStatus.Status -ne "Succeeded") {
            Throw ("Unknown error in inventory process. The specific error message is: {0}" -f $_.Exception.Message)
            Return
        }
    }
}

Function Update-TapeStatus ($liblist) {
    Foreach ($lib in $liblist) {
    write-host ("in tapestatus. the lib is: {0}" -f $lib)
        Write-Verbose ("Beginning the process to determine which tapes to mark 'free' on {0}" -f $lib)
        Write-Verbose ("Getting list of tapes in {0}." -f $lib)
        $tapes = Get-DPMTape -DPMLibrary $lib | Where {$_.Location -notmatch "*slot*"} | Sort Location

        Foreach ($tape in $tapes) {
            If ($tape.DisplayString -eq "Suspect") {
                Write-Verbose ("Remove suspect tapes from the DPM database.")
                Invoke-Command -ScriptBlock {osql -E -S server2 -d DPMDB_server1 -Q "UPDATE tbl_MM_ArchiveMedia SET IsSuspect = 0"} -whatif
                Start-DPMLibraryInventory -DPMLibrary $lib -FastInventory -Tape $tape -whatif
            }
            #Run a full inventory on "unknown" tapes
            #Make recyclable tapes "free"
            If (($tape.DisplayString -notlike "Free*" -and $tape.DataSetState -eq "Recyclable") -or ($tape.DisplayString -like "Unrecognized")) {
                Write-Output ("Marking the tape in slot {0} as free." -f $tape.Location)
                Set-DPMTape $tape -Free -whatif
            }
            If ($tape.OMIDState -eq "Unknown") {
                Write-Warning ("Unknown tape found in slot {0}. Beginning detailed inventory." -f $tape.location)
                $inventoryStatus = Start-DPMLibraryInventory -DPMLibrary $lib -DetailedInventory -Tape $tape -whatif
                While ($inventoryStatus.HasCompleted -eq $False) {Write-Output ("Running full inventory on the tape in slot {0} (label {1})" -f $tape.Location,$tape.Label); Start-Sleep 10}
            }
        }
    }
}

#Calling functions
Try {
    Import-DPMModule
}
Catch {
    Write-Error $_
    Exit
}

Try {
    $liblist = Get-Libraries
}
Catch {
    Write-Error $_
    Exit
}

Try {
    Inventory-DPMLibraries
}
Catch {
    Write-Error $_
    Exit
}

Update-TapeStatus $liblist

谢谢。

【问题讨论】:

    标签: debugging powershell dpm


    【解决方案1】:

    您的函数 Inventory-DPMLibraries 需要一个参数 ($liblist):

    Function Inventory-DPMLibraries ($liblist) {
      ...
    }
    

    但是,您在调用函数时不提供该参数:

    Try {
      Inventory-DPMLibraries
    }
    Catch {
      Write-Error $_
      Exit
    }
    

    把上面改成这样:

    Try {
      Inventory-DPMLibraries $liblist
    }
    Catch {
      Write-Error $_
      Exit
    }

    【讨论】:

    • 谢谢,这解决了第一个问题。我知道这很简单,因为我已经修复了一次 :) 现在,为什么 $liblist 参数在传递到 Update-TapeStatus 时是空白的?
    • "*slot*" 不是有效的正则表达式。 * 指定它前面的字符的“零个或多个”。由于您以* 开头,因此它前面没有字符。将-notmatch 更改为-notlike 或将正则表达式更改为简单的"slot"。或者,如果您希望匹配文字字符 *,请使用 "\*slot\*"
    猜你喜欢
    • 1970-01-01
    • 2011-10-12
    • 2017-03-29
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2012-12-03
    相关资源
    最近更新 更多