改进代码以在 PowerShell 中使用可选开关参数

Improve code to use optional switch parameter in PowerShell

我有一个包装 Invoke-WebRequest 的 Powershell 函数。 根据参数 $verbose 的值,我想使用 -Verbose 或不使用。

我使用 API 编写的代码可以正常工作...但我觉得应该有一种代码行数更少的更好方法。 Invoke-WebRequest

的行有两倍感觉不对

所以我的问题是:Powershell 中是否有处理开关参数的最佳方法?

函数如下:

function Invoke-MarkLogicManagementAPI($server, $apiFolder, $adminCredentials, $HTTPmethod, $body, $verbose)
{
    $resp1HTTPCode= "Not set"
    try
    {
        $uri = "http://$($server):8002/manage/v2/$apiFolder"
        if ($verbose -eq $true)
        {
            $resp1 = Invoke-WebRequest -Uri $uri -Body $body -Method "$HTTPmethod" -Credential $adminCredentials -ContentType "application/json" -ErrorAction SilentlyContinue -Verbose
        }
        else
        {
            $resp1 = Invoke-WebRequest -Uri $uri -Body $body -Method "$HTTPmethod" -Credential $adminCredentials -ContentType "application/json" -ErrorAction SilentlyContinue
        }
        $resp1HTTPCode = $resp1.StatusCode
    }
    catch [Exception]
    {
        $resp1HTTPCode = $_.Exception.Response.StatusCode.Value__
    }

    return $resp1HTTPCode
}

是的,您可以将布尔值传递给开关参数。你的情况:

-Verbose:$verbose

示例:

function DoSomething
{
    [CmdletBinding()]
    Param()
    Write-Verbose "output"
}

DoSomething -verbose:$true # Does write output
DoSomething -verbose:$false # no output

由于您的问题涉及 Verbose,因此使用 [CmdletBinding()] 是解决该差异的简单方法。我还想向您介绍 splatting,这是一种将不同数量的参数传递给 cmdlet 而不必实际写出每个命令的好方法。

function Get-Bagels{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True)]
        [string]$Filter,
        [switch]$Recurse=$false,
        [switch]$FilesOnly 
    )

    $parameters = @{
        Filter = $filter
        Recurse = $recurse
    }

    If($filesonly){$parameters.File=$True}

    Get-ChildItem @parameters
}

一个真正的简单示例是创建一个散列table $parameters并添加我们想要传递给Get-ChildItem的参数。我展示了几种填充 table 的方法,特别是您可以看到文件开关有条件地添加了一个小的 if

这样,无论使用什么参数,cmdlet 调用每次都是相同的。

所以下面的函数调用会起作用

Get-Bagels -Filter "*.txt"
Get-Bagels -Filter "*.txt" -Recurse
Get-Bagels -Filter "*.txt" -FilesOnly
Get-Bagels -Filter "*.txt" -Recurse:$False -FilesOnly