如何将参数传递给 PowerShell 脚本?

How can I pass an argument to a PowerShell script?

提问人:Boris Pavlović 提问时间:4/8/2011 最后编辑:Peter MortensenBoris Pavlović 更新时间:3/4/2023 访问量:925910

问:

有一个名为 PowerShell 脚本,可使 iTunes 快进 30 秒:itunesForward.ps1

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + 30
}

它是通过提示行命令执行的:

powershell.exe itunesForward.ps1

是否可以从命令行传递参数并将其应用于脚本中,而不是硬编码的 30 秒值?

PowerShell 命令行 自动化 参数传递 iTunes

评论


答:

782赞 Ocaso Protal 4/8/2011 #1

经测试可正常工作:

#Must be the first statement in your script (not counting comments)
param([Int32]$step=30) 

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + $step
}

powershell.exe -file itunesForward.ps1 -step 15

多个参数语法(注释是可选的,但允许):

<#
    Script description.

    Some notes.
#>
param (
    # height of largest column without top bar
    [int]$h = 4000,
    
    # name of the output image
    [string]$image = 'out.png'
)

还有一些高级参数的例子,例如 Mandatory

<#
    Script description.

    Some notes.
#>
param (
    # height of largest column without top bar
    [Parameter(Mandatory=$true)]
    [int]$h,
    
    # name of the output image
    [string]$image = 'out.png'
)

Write-Host "$image $h"

默认值不适用于必需参数。您可以省略 boolean 类型的高级参数。=$true[Parameter(Mandatory)]

评论

10赞 Andrew Gray 11/2/2015
如果参数是字符串怎么办?语法是什么?是 -step '15' 还是 -step '15'
10赞 Ocaso Protal 11/2/2015
@Andrew 首先,您必须将参数的类型更改为 .如果随后要将字符串作为参数传递,则可以使用 或 。如果字符串中没有空格(或引号),您甚至可以省略引号。[string]'"
85赞 Josh Padnick 12/30/2015
仅供参考,要使用多个参数,请使用以下语法:param([string]$env,[string]$s3BucketName)
3赞 Charles 2/23/2016
它缺少“-file”。在我添加这个之前,它对我不起作用。查看完整代码:powershell.exe -file itunesForward.ps1 -step 15
2赞 Ocaso Protal 2/23/2016
@Charles 谢谢你的提示。你是对的:通话中缺少。没有的调用可能适用于 Powershell 版本 1.0,但我无法测试它。更新了答案。-file
431赞 Emiliano Poggi 4/8/2011 #2

您还可以使用变量(类似于位置参数):$args

$step = $args[0]

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + $step
}

那么它可以这样称呼:

powershell.exe -file itunersforward.ps1 15

评论

65赞 ADTC 7/14/2012
发现这比公认的解决方案更容易,而且您可以直接在脚本中的任何位置使用 $args[0](无需第一行)。PS:关于将字符串作为参数传递的提示:它们必须用单引号括起来。
37赞 Florin Dumitrescu 11/22/2013
这和公认的解决方案都有效,主要区别在于它按位置读取参数,而接受的解决方案按名称读取参数。当需要传递多个参数时,按名称传递可能更清晰。
6赞 Pete 7/22/2015
接受的解决方案中的命名参数也会自动填充 Get-Help
3赞 Emiliano Poggi 9/1/2016
这个答案引起了如此多的关注,请查看更完整的相关答案。stackoverflow.com/questions/6359618/......
9赞 ZEE 11/9/2018 #3

让 PowerShell 分析并确定数据类型。为此,它在内部使用“变体”。

总的来说,它做得很好......

param($x)
$iTunes = New-Object -ComObject iTunes.Application
if ($iTunes.playerstate -eq 1)
{
    $iTunes.PlayerPosition = $iTunes.PlayerPosition + $x
}

或者,如果需要传递多个参数:

param($x1, $x2)
$iTunes = New-Object -ComObject iTunes.Application
if ($iTunes.playerstate -eq 1)
{
    $iTunes.PlayerPosition = $iTunes.PlayerPosition + $x1
    $iTunes.<AnyProperty>  = $x2
}
5赞 JDennis 12/20/2018 #4

在文件中使用以下代码创建 PowerShell 脚本。

param([string]$path)
Get-ChildItem $path | Where-Object {$_.LinkType -eq 'SymbolicLink'} | select name, target

这将创建一个带有 path 参数的脚本。它将列出所提供路径内的所有符号链接以及符号链接的指定目标。

3赞 Froggy 5/16/2019 #5

还可以直接在 PowerShell 命令行中定义变量,然后执行脚本。变量也将在那里定义。这在我无法修改已签名脚本的情况下帮助了我。

例:

 PS C:\temp> $stepsize = 30
 PS C:\temp> .\itunesForward.ps1

iTunesForward.ps1 为

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + $stepsize
}
42赞 Joma 10/19/2019 #6

从批处理文件 (*.bat) 或 CMD 调用脚本

PowerShell 核心

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param1 Hello -Param2 World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "path-to-script/Script.ps1 -Param1 Hello -Param2 World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello -Param2 World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param2 World Hello"

PowerShell

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param1 Hello -Param2 World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "path-to-script/Script.ps1 -Param1 Hello -Param2 World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello -Param2 World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param2 World Hello"

从 PowerShell 调用

PowerShell Core 或 Windows PowerShell

& path-to-script/Script.ps1 -Param1 Hello -Param2 World
& ./Script.ps1 -Param1 Hello -Param2 World

Script.ps1 - 脚本代码

param(
    [Parameter(Mandatory=$True, Position=0, ValueFromPipeline=$false)]
    [System.String]
    $Param1,

    [Parameter(Mandatory=$True, Position=1, ValueFromPipeline=$false)]
    [System.String]
    $Param2
)

Write-Host $Param1
Write-Host $Param2

评论

0赞 FilBot3 9/5/2020
该设置是否会将其转换为位置参数而不是标志?Position=0
1赞 Joma 9/7/2020
如果不使用参数名称,则需要发送与位置相关的正确值。检查此答案的更新。
8赞 Norberto Castellanos 2/15/2020 #7
# ENTRY POINT MAIN()
Param(
    [Parameter(Mandatory=$True)]
    [String] $site,
    [Parameter(Mandatory=$True)]
    [String] $application,
    [Parameter(Mandatory=$True)]
    [String] $dir,
    [Parameter(Mandatory=$True)]
    [String] $applicationPool
)

# Create Web IIS Application
function ValidateWebSite ([String] $webSiteName)
{
    $iisWebSite = Get-Website -Name $webSiteName
    if($Null -eq $iisWebSite)
    {
        Write-Error -Message "Error: Web Site Name: $($webSiteName) not exists."  -Category ObjectNotFound
    }
    else
    {
        return 1
    }
}

# Get full path from IIS WebSite
function GetWebSiteDir ([String] $webSiteName)
{
    $iisWebSite = Get-Website -Name $webSiteName
    if($Null -eq $iisWebSite)
    {
        Write-Error -Message "Error: Web Site Name: $($webSiteName) not exists."  -Category ObjectNotFound
    }
    else
    {
        return $iisWebSite.PhysicalPath
    }
}

# Create Directory
function CreateDirectory([string]$fullPath)
{
    $existEvaluation = Test-Path $fullPath -PathType Any
    if($existEvaluation -eq $false)
    {
        new-item $fullPath -itemtype directory
    }
    return 1
}

function CreateApplicationWeb
{
    Param(
        [String] $WebSite,
        [String] $WebSitePath,
        [String] $application,
        [String] $applicationPath,
        [String] $applicationPool
        )
    $fullDir = "$($WebSitePath)\$($applicationPath)"
    CreateDirectory($fullDir)
    New-WebApplication -Site $WebSite -Name $application -PhysicalPath $fullDir -ApplicationPool $applicationPool -Force
}

$fullWebSiteDir = GetWebSiteDir($Site)f($null -ne $fullWebSiteDir)
{
    CreateApplicationWeb -WebSite $Site -WebSitePath $fullWebSiteDir -application $application  -applicationPath $dir -applicationPool $applicationPool
}

评论

0赞 Norberto Castellanos 2/15/2020
它有效 .\create-application-pool.ps1 -site xx_8010 -application AppTest -dirtestDir -applicationPool TestAppPool
0赞 Dan Atkinson 3/4/2023 #8

在我的特定用例中,我想从配置文件中访问参数,该配置文件忽略了 ,并简单地检查参数(本质上是一个开关)的存在params

我有一个批处理脚本,它运行一个 ps1 文件,但带有配置文件。这会在加载时输出文本。在某些脚本中,如果我不需要该文本,我想禁用该文本的输出。为此,我创建了一些简单的开关,例如下面的示例。profile.ps1

这是一个非常基本的版本,但如果你愿意,你可以扩展它。以“静默运行”模式为例,然后...

在我的批处理脚本中:

C:\path\to\pwsh.exe -Command "%~dpn0.ps1" -QuietProfile

PowerShell 脚本(在 profile.ps1 中):

[Boolean]$global:QuietProfile = [Boolean]([Environment]::GetCommandLineArgs() -match "-QuietProfile")

if (-not $global:QuietProfile) {
  Write-Host "I am some text which should not appear when -QuietProfile is passed"
}

默认情况下(如果您刚刚打开了 pwsh.exe),则该值将为 false,您将看到输出正常。$global:QuietProfile