ChatGPT解决这个技术问题 Extra ChatGPT

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

有一个名为 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 秒值?


O
Ocaso Protal

测试为工作:

#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

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

<#
    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 版,但我无法对其进行测试。更新了答案。
P
Peter Mortensen

您还可以使用 $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:关于将字符串作为参数传递的提示:它们必须用单引号括起来。
这和公认的解决方案都有效,主要区别在于它按位置读取参数,而公认的解决方案按名称读取。当需要传递多个参数时,按名称传递可能会更简洁。
已接受解决方案中的命名参数也会自动填充 get-help
这个答案受到了如此多的关注,请查看更完整的相关答案。 stackoverflow.com/questions/6359618/…
J
Joma

从批处理文件 (*.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.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 核心或 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 设置是否将其变成位置参数而不是标志?
如果您不使用参数名称,则需要发送有关位置的正确值。检查此答案的更新。
P
Peter Mortensen

让 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
}

P
Peter Mortensen

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

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

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


P
Peter Mortensen
# 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
F
Froggy

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