改进代码以在 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
我有一个包装 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