首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修复这个位置参数错误(PowerShell)?

如何修复这个位置参数错误(PowerShell)?
EN

Stack Overflow用户
提问于 2022-01-25 18:38:43
回答 2查看 1.1K关注 0票数 1

我编写了这个PowerShell指令,以将给定的路径添加到新的PowerShell进程中的Microsoft排除列表中(具有提升的权限):

代码语言:javascript
复制
Start-Process powershell {Add-MpPreference -ExclusionPath "my/path/to/exe"; Read-Host;} -Verb "RunAs"

令人惊讶的是,我得到了这个错误:

代码语言:javascript
复制
Add-MpPreference : A positional parameter cannot be found that accepts argument '-'.

但是,如果我运行下面的行,输出(hi)将成功地显示在新进程中:

代码语言:javascript
复制
Start-Process powershell {echo "hi"; Read-Host} -Verb "RunAs"

第一个PowerShell指令有什么问题?我怎么才能解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-25 19:46:13

在@mclement0的帮助下(请参阅上面的注释),我意识到我不得不使用带有Start-Process的双引号字符串来使指令工作:

代码语言:javascript
复制
Start-Process powershell "Add-MpPreference -ExclusionPath 'my/path/to/exe'" -Verb "RunAs"
票数 2
EN

Stack Overflow用户

发布于 2022-01-27 04:23:03

使用命名参数

对于稍后来并寻求帮助的人,请使用错误信息:

代码语言:javascript
复制
<cmdlet>: A positional parameter cannot be found that accepts argument '<arg>'.

快速修复方法是使用命名参数。命名参数总是有效的。

代码语言:javascript
复制
# Doesn't work. The parameter name *is not* given. 
Get-ChildItem 32

# Works. The parameter name *is* given. 
Get-ChildItem -Depth 32

列表位置参数

或者,您可以检查cmdlet是否有任何位置参数。你可以搜索文档。但是一个快速的方法是让PowerShell来完成这项工作。使用下面的单线衬垫。然后用你感兴趣的cmdlet替换"Get-ChildItem“。请记住,如果输出仅显示“命名”,则cmdlet不接受位置参数。下面有两个位置参数:路径和过滤器。

代码语言:javascript
复制
Get-Help -Name "Get-ChildItem" -Parameter * | 
  Sort-Object -Property position | 
  Select-Object -Property name, position                                  

name          position
----          --------
Path          0
Filter        1
Attributes    Named
Depth         Named
Directory     Named
Exclude       Named
File          Named
FollowSymlink Named
Force         Named
Hidden        Named
Include       Named
LiteralPath   Named
Name          Named
ReadOnly      Named
Recurse       Named
System        Named

什么是位置参数?

参数是添加到命令中以更改命令工作方式的文本。“参数”一词通常指的是参数名称和参数值。参数名称前面有一个连字符'-‘

代码语言:javascript
复制
# | cmdlet       | parameter name  
# v              v     v parameter value
  Get-ChildItem -Path './'

大多数cmdlet提供了省略参数名称的快捷方式。这些都被称为位置参数。而cmdlet开发人员不需要支持位置参数。

代码语言:javascript
复制
# | cmdlet
# v              v positional parameter
  Get-ChildItem './'

由于位置参数是未命名的,因此区分它们的唯一方法是根据它们在语句中的位置--名称位置参数--来区分它们。您可以通过使用Get-Help cmdlet、使用Microsoft联机或通过检查cmdlet供应商的文档来找到与您感兴趣的参数关联的位置。您可能需要进行一些搜索,因为参数是按名称而不是在帮助页中的位置进行索引的。第一个位置编号为0。随后的头寸增加了1。所以前四个位置是0,1,2,3…下面,我们可以看到Get的路径参数在0位置被接受.这是在以“立场?”开头的行上表示的。

代码语言:javascript
复制
Get-Help -Name "Get-ChildItem" -Parameter "Path" 

-Path <string[]>
    
    Required?                    false
    Position?                    0
    Accept pipeline input?       true (ByValue, ByPropertyName)
    Parameter set name           Items
    Aliases                      None
    Dynamic?                     false
    Accept wildcard characters?  false

命名参数将显示“命名”作为其位置值。

代码语言:javascript
复制
Get-Help -Name "Get-ChildItem" -Parameter "LiteralPath"

-LiteralPath <string[]>
    
    Required?                    true
    Position?                    Named
    Accept pipeline input?       true (ByPropertyName)
    Parameter set name           LiteralItems
    Aliases                      PSPath, LP
    Dynamic?                     false
    Accept wildcard characters?  false

通过在线阅读参数帮助主题了解更多信息。

错误信息详细信息

我希望能够从最初的查询中解释错误信息。但我没有得出结论。

查看文档,附加-MpPreference是不寻常的,因为它没有位置参数。

我的系统上没有要测试的Add-MpPreference cmdlet的副本。我发现Get-Unique是一个类似的cmdlet。我在Get-Unique中也产生了类似的错误

代码语言:javascript
复制
@("hello","hello") | get-unique -

         Get-Unique: A positional parameter cannot be found that accepts argument '-'. 
# Add-MpPreference : A positional parameter cannot be found that accepts argument '-'.

所以我们必须考虑一下,如果有任何位置参数可用的话。我们可以看到代码和错误信息的比较。

从PowerShell 7开始,我们可以获得关于Get-Error上一条错误消息的更多信息。默认情况下,早期版本的PowerShell将打印大部分这些信息。但是PowerShell 7切换到了更简单的错误消息。

如果向下滚动到PositionMessage,它将告诉您是哪一行代码导致了执行错误。它将绘制一个小的图表,其中违规的表达式加下划线。这使得将错误连接到特定语法变得更加容易。

代码语言:javascript
复制
Get-Error                                                

...

PositionMessage  : At line:1 char:22
                       + @("hello","hello") | get-unique -
                       +                      ~~~~~~~~~~~~

检查不良字符

有时,如果我们从网上复制和粘贴,我们可以选择排版字符,这些字符适合打印,但不适用于代码。例子包括聪明的引号(卷曲)和各种破折号,如emdash t(它比标准的破折号长)。Conhost和Windows终端应该能够处理这些问题。但我不确定脚本或其他主机(比如NSIS内部)。

检查的一种方法是转到shell并使用Format-Hex检查可疑代码的简短片段。我们需要使用这里-字符串来保留原始格式。

下面,我将错误消息复制到shell,并将其签出。我想知道结尾的连字符是否有正确的字符代码。我们可以在字节0x51或行50和列01处看到代码。那里的值是0x2D。我们可以通过直接在命令行输入连字符来检查它的正确值。一定要把它用引号括起来。经过第二次检查,我们看到正确的值是0x2D。因为我们正在调查的值匹配正确的值,所以看起来连字符并不是问题所在。如果您自己这样做,请确保从您的代码编辑器中复制,而不是任何错误消息,这是我不得不在这里使用的妥协。

代码语言:javascript
复制
@"
Add-MpPreference : A positional parameter cannot be found that accepts argument '-'.
"@ | Format-Hex

   Label: String (System.String) <44085160>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 41 64 64 2D 4D 70 50 72 65 66 65 72 65 6E 63 65 Add-MpPreference
0000000000000010 20 3A 20 41 20 70 6F 73 69 74 69 6F 6E 61 6C 20  : A positional 
0000000000000020 70 61 72 61 6D 65 74 65 72 20 63 61 6E 6E 6F 74 parameter cannot
0000000000000030 20 62 65 20 66 6F 75 6E 64 20 74 68 61 74 20 61  be found that a
0000000000000040 63 63 65 70 74 73 20 61 72 67 75 6D 65 6E 74 20 ccepts argument 
0000000000000050 27 2D 27 2E                                     '-'.


'-' | Format-Hex

   Label: String (System.String) <6ECC1D05>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 2D                                              -

powershell.exe命令参数

我想一步一步地检查这个命令,看看是否有任何细微的语法错误。我在我的系统上碰到了一个不相关的bug,使我无法走得很远。但是,经过一番思考,我不知道为什么这些例子会奏效。在这种情况下,Start-Process应该将参数强制给[String[]]powershell.exe应该将第一个字符串解释为文件名,而不是cmdlet。确实,powershell.exe可以识别没有参数名称的脚本块。但这并不适用于这里,因为强制的[String[]]

如果接受的答案(与启动过程和引用相关)没有帮助,那么您可以为powershell.exe使用适当的参数。或者,当从PowerShell调用程序时,您可能需要探索引用和逃避的兔子洞。

代码语言:javascript
复制
#             | Interprets strings as file names. 
#             |           |----------- String passed to powershell.exe --------------| 
#             v           |  not a file                                              |  
Start-Process powershell {Add-MpPreference -ExclusionPath "my/path/to/exe"; Read-Host;} -Verb "RunAs"
Start-Process powershell "Add-MpPreference -ExclusionPath 'my/path/to/exe'"             -Verb "RunAs"

Microsoft powershell.exe帮助

Microsoft pwsh.exe帮助

传递参数的一般信息

外部可执行文件的参数不能正确转义\ GitHub问题

引用Start-Process中的问题-特别是GitHub问题

引用关于Azure CLI \ GitHub医生的建议

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70853968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档