【问题标题】:How can I pass an argument to a PowerShell script?如何将参数传递给 PowerShell 脚本?
【发布时间】:2011-08-01 08:11:56
【问题描述】:

有一个名为 itunesForward.ps1 的 PowerShell 脚本可以让 iTunes 快进 30 秒:

$iTunes = New-Object -ComObject iTunes.Application

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

使用提示行命令执行:

powershell.exe itunesForward.ps1

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

【问题讨论】:

    标签: powershell command-line automation parameter-passing itunes


    【解决方案1】:

    测试为工作:

    #Must be the first statement in your script (not coutning 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
    

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

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

    还有一些advanced parameters 的例子,例如强制

    <#
        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"
    

    默认值不适用于强制参数。对于布尔型[Parameter(Mandatory)] 的高级参数,您可以省略=$true

    【讨论】:

    • 如果参数是字符串怎么办?语法是什么?是像 -step '15' 还是 -step "15"
    • @Andrew 首先,您必须将参数的类型更改为[string]。如果您想传递一个字符串作为参数,您可以使用'"。如果字符串中没有空格(或引号),您甚至可以省略引号。
    • 仅供参考,要使用多个参数,请使用以下语法:param([string]$env,[string]$s3BucketName)
    • 缺少“-file”。在我添加这个之前,它对我不起作用。查看完整代码:powershell.exe -file itunesForward.ps1 -step 15
    • @Charles 感谢您的提示。你是对的:电话中缺少-file。没有的调用可能适用于 Powershell 1.0 版,但我无法对其进行测试。更新了答案。
    【解决方案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
    

    【讨论】:

    • 发现这比公认的解决方案更容易,而且您可以直接在脚本中的任何位置使用 $args[0](无需位于第一行)。 PS:关于将字符串作为参数传递的提示:它们必须用单引号括起来。
    • this 和接受的解决方案都有效,主要区别在于它按位置读取参数,而接受的解决方案按名称执行。当需要传递多个参数时,按名称传递可能会更简洁。
    • 已接受解决方案中的命名参数也会自动填充 get-help
    • 这个答案备受关注,请查看更完整的相关答案。 stackoverflow.com/questions/6359618/…
    【解决方案3】:

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

    PowerShell Core

    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
    

    【讨论】:

    • Position=0 设置是否将其变成位置参数而不是标志?
    • 如果您不使用参数名称,则需要发送有关位置的正确值。检查此答案的更新。
    【解决方案4】:

    让 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】:

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

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

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

      【讨论】:

        【解决方案6】:
        # 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
        }
        

        【讨论】:

        • 成功了。\create-application-pool.ps1 -site xx_8010 -application AppTest -dirtestDir -applicationPool TestAppPool
        【解决方案7】:

        您也可以直接在 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
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-11-19
          • 2015-06-07
          • 2017-05-08
          • 2019-07-07
          • 2020-09-04
          • 2012-05-05
          • 2013-11-24
          相关资源
          最近更新 更多