本文目录
怎样将一个脚本稍作润色,让它能够根据用户的输入,处理并输出相应的结果,而不是只产生一成不变的输出。怎样将参数传递给脚本,这是本篇讨论的内容。
$args返回所有的参数
传递给一个函数或者一个脚本的参数都保存在$args变量中。可以先打开记事本,输入脚本:
Write-Host "Hello,$args"
保存后,通过控制台执行脚本:
PS E:> notepad myscript.ps1 PS E:> .MyScript.ps1 Hello, PS E:> .MyScript.ps1 "Mosser Lee" Hello,Mosser Lee
$args数组参数
默认情况下,传递给一个Powershell脚本的参数类型为数组,例如:
PS E:> .MyScript.ps1 My Website Is www.mossfly.com Hello,My Website Is www.mossfly.com
上面的文本中包含多个连续的空格,可是当脚本把参数输出时却不存在连续的空格了。那是因为脚本会把文本根据白空格截断并转换成数组。如果不想文本被当成数组那就把它放在引号中。
PS E:> .MyScript.ps1 "My Website Is www.mossfly.com" Hello,My Website Is www.mossfly.com
在$args中逐个访问参数
因为$args是一个数组,自然可以通过索引访问数组的每一个元素。可以将MyScript.sp1的内容改为:
For($i=0;$i -lt $args.Count; $i++) { Write-Host "parameter $i : $($args[$i])" }
然后在控制台测试:
PS E:> .MyScript.ps1 www moss fly com parameter 0 : www parameter 1 : moss parameter 2 : fly parameter 3 : com
在脚本中使用参数名
通过Powershell传递参数固然方便,但是如果用户不知道参数的传递顺序,也是很郁闷的,例如在Myscript.ps1中输入:
$args[0]-$args[1]
执行脚本发现参数的顺序不同,结果也不同:
PS E:> Get-Content .MyScript.ps1 $args[0]-$args[1] PS E:> .MyScript.ps1 10 8 2 PS E:> .MyScript.ps1 8 10 -2
所以最好的方式给参数指定名称,输入以下的脚本:
param($Directory,$FileName) "Directory= $Directory" "FileName=$FileName"
其中param给参数指定名称。
执行脚本:
PS E:> .MyScript.ps1 -Directory $env:windir -FileName config.xml Directory= C:windows FileName=config.xml PS E:> .MyScript.ps1 -FileName config.xml -Directory $env:windir Directory= C:windows FileName=config.xml
验证参数
给脚本的参数绑定数据类型,绑定帮助信息。一旦脚本缺少参数,或者输入的参数类型不正确,就提醒用户:
输入脚本:
param( [string]$Name=$(throw "Parameter missing: -name Name") , [int]$Age=$(throw "Parameter missing: -age x as number") ) "Name= $Name" "Age=$Age"
执行脚本:
PS E:> .MyScript.ps1 Parameter missing: -name Name 所在位置 E:MyScript.ps1:2 字符: 22 + [string]$Name=$(throw < <<< "Parameter missing: -name Name") , + CategoryInfo : OperationStopped: (Parameter missing: -name Name:String) [], Runtime Exception + FullyQualifiedErrorId : Parameter missing: -name Name PS E:> .MyScript.ps1 -Name mosser Parameter missing: -age x as number 所在位置 E:MyScript.ps1:3 字符: 18 + [int]$Age=$(throw < <<< "Parameter missing: -age x as number") + CategoryInfo : OperationStopped: (Parameter missing: -age x as number:String) [], R untimeException + FullyQualifiedErrorId : Parameter missing: -age x as number PS E:> .MyScript.ps1 -Name mosser -Age abc E:MyScript.ps1 : 无法处理对参数“Age”的参数转换。无法将值“abc”转换为类型“System.Int32”。错误: “输入字符串的格式不正确。” 所在位置 行:1 字符: 33 + .MyScript.ps1 -Name mosser -Age < <<< abc + CategoryInfo : InvalidData: (:) [MyScript.ps1], ParameterBindin...mationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,MyScript.ps1 PS E:> .MyScript.ps1 -Name mosser -Age 100 Name= mosser Age=100
变量的作用域
Powershell默认使用全局作用域global: ,但是在函数和脚本中分别使用函数作用域function:和脚本作用域script: 。
一旦脚本执行结束,存在于脚本作用域的变量也会消失。但是有一点,如果一个变量在脚本外定义,在脚本内没有定义,在脚本内使用时会把外面的变量引渡过来。
在脚本中输入:
$temp
执行脚本:
PS E:> .MyScript.ps1 PS E:> $temp="mosser lee" PS E:> .MyScript.ps1 mosser lee
在脚本中尝试改变变量$temp,但是脚本内的变量不会影响脚本外的变量,输入脚本:
$temp="www.mossfly.com" $temp
执行脚本:
PS E:> .MyScript.ps1 www.mossfly.com PS E:> $temp mosser lee
本文链接: https://www.pstips.net/powershell-pass-args-to-scripts.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
Hello,Mooser Lee!最近在用powershell写一个自动升级站点的脚本,所以在学习powershell,期间看了你很多教程,对我帮助确实很大,Thank you!
这个文章不错,今天用到了。我在站内搜索参数找到这篇文章,很方便。
我使用上面“验证参数”的代码,但是[string]$Name=$(throw “Parameter missing: -name Name”) ,这行却提示我The assignment expression is not valid. the input to an assignment operator must be an object that is able to accept assignments, suach as a variable or a property.
我用我家里的电脑试了一下也是这样。
我估计你验证的使用方法不正确。
你把具体的步骤贴出来我看看。
#Get VMs on server
Function GetVMSnapshots($ServerName, $ComputerName, $SnapshotName)
{
if($Script:IsWin10)
{
$VmSnapshots = Invoke-Command -ScriptBlock {Get-VM -ComputerName $ServerName | Get-VMSnapshot -Name $SnapshotName} -ComputerName $ServerName
}
else
{
$VmSnapshots = Get-VM -ComputerName $ServerName | Get-VMSnapshot -Name $SnapshotName
}
return $VmSnapshots
}
#Switch to a snapshot
Function SwitchSnapshot($vm, $ServerName)
{
if($Script:IsWin10)
{
Invoke-Command -ScriptBlock {$vm | Resume-VM} -ComputerName $ServerName
}
else
{
$vm | Resume-VM
}
}
#Will snapshot to start if its status is closed
Function StartupVM($vm, $ServerName)
{
if($Script:IsWin10)
{
Invoke-Command -ScriptBlock {$vm | Start-VM} -ComputerName $ServerName
}
else
{
$vm | Start-VM
}
}
#judge whether is Windows10, due to powershell version on Win10 is incompatible with servers’,
#it needs to special processing
Function IsWin10
{
$version = Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExcludeProperty Caption
if($version.Version.Split(“.”)[0] -eq ’10’)
{
return $true
}
else
{
return $false
}
}
param(
[string] $servername = $(throw “Parameter of server name should be string”),
#search for all of computers on the server that snapshot names named as $snapshotname if this parameter is null,
#otherwise search for specify the snapshot of the computer on the server
[string] $computername,
[string] $snapshotname = $(throw “Parameter of snapshot name should be string”)
)
$Script:IsWin10 = IsWin10
$vm = GetVMs -ServerName $servername -ComputerName $computername -SnapshotName $snapshotname
SwitchSnapshot -vm $vm -ServerName $servername
会不会是位置的问题啊,我把param这块移到最上面好像就没有这个问题了
当然,param必须放在函数或者脚本文件的开始。
好文章,希望博主坚持下去!
不错,感谢讲解.
广播: cmd脚本笔记 – 震惊部