调用操作符“&”虽然简短,但是给我们执行Powershell命令提供了很大的方便。如果你之前将Powershell命令存储在了一个字符串中,或者一个变量中。此时,调用操作符就可以将字符串直接解释成命令并执行,如果在Powershell控制台中,你只须要输入即可。具体,如下:
#将命令存储在变量中:
$command = "Dir"
# 如果直接输出变量,字符串原样输出。
$command
#Dir
#如果使用调用操作符"&"
& $command
目录: E:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2012/5/9 0:42 Blog
d---- 2012/5/23 21:45 DooMLoRD_v3_ROOT-zergRush-busybox-
su
d---- 2012/6/1 20:21 Haitch-TFS
d---- 2012/3/25 15:32 KillProcess
调用操作符只能接受单个命令
但是调用操作符不能接受全部的Powershell脚本或命令,只能接受单个的一条命令,例如使用:
$command = "Dir $env:windir"
& $command
就会报错
无法将“Dir C:windows”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后重试。
所在位置 E:MyScript.ps1:6 字符: 2
+ & <<<< $command
+ CategoryInfo : ObjectNotFound: (Dir C:windows:String) [], Comm
andNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
为什么会这样呢?追根溯源,Powershell中的调用符,首先会使用get-command去发现命令是否可用,而get-command的确只支持单独的一条命令,不支持命令串或者脚本串。 调用操作符执行CommandInfo对象 调用操作符初始化时会将指定的文本传递给get-command,然后有get-command去检索命令,事实上,调用操作符甚至可以直接执行一个CommandInfo对象,绕过自身的内部get-command,例如:
PS E:> $command=Get-Command tasklist PS E:> $command CommandType Name ----------- ---- Application tasklist.exe PS E:> & $command 映像名称 PID 会话名 会话# 内存使用 ========================= ======== ================ =========== ============ System Idle Process 0 Services 0 24 K System 4 Services 0 560 K smss.exe 356 Services 0 756 K csrss.exe 564 Services 0 3,744 K csrss.exe 680 Console 1 71,512 K wininit.exe 688 Services 0 2,904 K services.exe 740 Services 0 8,552 K lsass.exe 764 Services 0 10,676 K lsm.exe 776 Services 0 3,240 K
通过命令名称唯一标识一条命令
但是可能存在别名,命令,函数的的名称一样,那Powershell会不会纠结到底执行哪个呢?当然不会,因为它们之间是有一个优先级的。从高到底,依次为:
Alias(1)
Function(2)
Filter(2)
Cmdlet(3)
Application(4)
ExternalScript(5)
Script (-)
下面举个例子:
PS E:> function Ping(){"我是Ping函数"}
PS E:> Set-Alias -Name Ping -Value echo
CommandType Name Definition
----------- ---- ----------
Alias Ping echo
Function Ping param()...
Application PING.EXE C:windowsSYSTEM32PING.EXE
PS E:> ping "测试我的Ping,估计执行的别名echo"
测试我的Ping,估计执行的别名echo
PS E:> del Alias:Ping
PS E:> ping ; #别名已经被删除,估计执行的是函数PING
我是Ping函数
PS E:> del Function:Ping
PS E:> ping baidu.com ; #函数已经被删除,估计执行的是函数ping 程序
正在 Ping baidu.com [220.181.111.85] 具有 32 字节的数据:
请求超时。
请求超时。
请求超时。
请求超时。
220.181.111.85 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 0,丢失 = 4 (100% 丢失),
那怎样突破优先级的限制执行指定的命令呢?方法都是大同小异,通过特定信息过滤到指定的CommandInfo对象,然后直接使用我们本篇的调用操作符。例如当存在如下的命令Ping命令
CommandType Name
----------- ----
Alias Ping
Function Ping
Application PING.EXE
我想调用第三个,可以使用:
PS E:> $command=Get-Command -Name ping | where {$_.CommandType -eq "Application" }
PS E:> & $command
用法: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
[-r count] [-s count] [[-j host-list] | [-k host-list]]
[-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name
选项:
-t Ping 指定的主机,直到停止。
若要查看统计信息并继续操作 - 请键入 Control-Break;
若要停止 - 请键入 Control-C。
-a 将地址解析成主机名。
-n count 要发送的回显请求数。
-l size 发送缓冲区大小。
-f 在数据包中设置“不分段”标志(仅适用于 IPv4)。
-i TTL 生存时间。
-v TOS 服务类型(仅适用于 IPv4。该设置已不赞成使用,且
对 IP 标头中的服务字段类型没有任何影响)。
-r count 记录计数跃点的路由(仅适用于 IPv4)。
-s count 计数跃点的时间戳(仅适用于 IPv4)。
-j host-list 与主机列表一起的松散源路由(仅适用于 IPv4)。
-k host-list 与主机列表一起的严格源路由(仅适用于 IPv4)。
-w timeout 等待每次回复的超时时间(毫秒)。
-R 同样使用路由标头测试反向路由(仅适用于 IPv6)。
-S srcaddr 要使用的源地址。
-4 强制使用 IPv4。
-6 强制使用 IPv6。
#或者& (Get-Command -Name ping)[2]
本文链接: https://www.pstips.net/powershell-call-operator.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

博主你好,
使用: $command=Get-Command -Name ping | where {$_.CommandType -eq “Application” } 语句得到的 $command 为null,
而使用 $command = Get-Command -Name ping -CommandType Application 可以得到对象.
我的是3.0,不知道是不是版本问题?
可能原书比较老。
get-command在新版里缺省只返回最高优先级的命令,文中例子在5.0的ps里要加上-all选项,或者用-CommandType Application指定类型。
get-command在ps5.0里缺省只返回最高优先级的命令,文中例子在5.0的ps里要加上-all选项。
$command = “Dir $env:windir”
& $command
这句在新版PS(5.0)里报错,如果去掉dir后面的参数以及空格就可以运行正常。
第一个命令框里的内容容易引起歧义……
$command = “dir $env:windir”
& $command执行会出错
$command = “dir”
& $command执行正确
确实是,第一个例 子中写错了,应该是 $Command=”dir”, 这样下面的展示内容才对得上。
现在的版本V5上,& {dir $env:windir} 可以运行,但是 $c=”{dir $env:windir}”
& $c 却不能运行。
单纯的这样写{dir C:\Windows},PowerShell解释器会认为它是语句块,可以用& 来执行。
& 后面的跟的参数,必须是一个cmdlet,函数名,脚本文件,或者语句块,或者可运行程序。
无法将“{dir C:\Windows}”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
感谢反馈,已更新
楼主,请教下如果把执行下面的命令,我想把一个字符串$PktCapCmd当做指令来执行?
$PktCapCmd=”${PktCapExe} -tests sp1bench -sp1bench Testcaseid=$TcNum”