Where-Object和$ env:SystemRoot,$ env:ProgramFiles,$ env:ProgramFiles(x86)

时间:2016-02-23 09:58:24

标签: powershell

我写了以下命令管道:

get-process | where {$_.Path -notmatch ${env:SystemRoot} -and $_.Path -notmatch ${env:ProgramFiles} -and $_.Path -notmatch ${env:ProgramFiles(x86)} | select path, name

我收到了错误:

parsing "C:\Program Files" - Malformed \p{X} character escape.
At line:1 char:22
+ get-process | where {$_.Path -notmatch $env:SystemRoot -and $_.Path -notmatch $e ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException

我明白发生了什么,我做了几次测试。我使用带有和不带escape字符的路径调用Get-ChildItem cmdlet。一切正常。我输入了Where-Object FilterScript参数脚本块,其中包含带有和不带“\”的路径。包含escape char的路径的Where-Object正常工作但是当我在Where-Object中放置没有escape char的路径时 - 我总是得到错误。

这不是系统环境变量的问题。我用“C:\ Program Files”定义了变量ProgramFilesA,用“C:\ Program Files”定义了变量ProgramFilesB。当我在$env:ProgramFilesA中使用Where-Object时出现错误,当我使用$env:ProgramFilesB时,一切正常。

如何在$env: cmdlet中调用包含路径的标准Where-Object变量来运行它而不会出错?

2 个答案:

答案 0 :(得分:0)

您可以使用Regex转义。

以下内容应该有效:

get-process | where {$_.Path -notmatch [Regex]::escape($env:SystemRoot) -and $_.Path -notmatch [Regex]::escape(${env:ProgramFiles(x86)}) -and $_.Path -notmatch [Regex]::escape(${env:ProgramFiles(x86)}) } | select path, name

如果您正在尝试运行不在程序文件和系统根目录的子文件夹中的进程;您可能希望修改通配符(以任何路径开头)的匹配表达式。

答案 1 :(得分:0)

此问题是因为您正在使用-match这是一个使用正则表达式的运算符,而您并未正确转义正则表达式元字符。这就是错误试图告诉你的:

  

Malformed \p{X} character escape

\p是P"程序文件"。正则表达式中的\pused for matching code points

您可以改用-like。我们在这里使用双引号来允许变量扩展。

get-process | where {$_.Path -notlike "$($env:SystemRoot)*" -and $_.Path  -notlike "$($env:ProgramFiles)*" -and $_.Path -notlike "(${env:ProgramFiles(x86)})*"}

如果您确实想要使用正则表达式,那么也可以收集这些环境变量并使用它们制作正确的正则表达式字符串。

$regex = "^(" + (($env:SystemRoot, $env:ProgramFiles, ${env:ProgramFiles(x86)} | ForEach-Object{[regex]::Escape($_)}) -join "|") + ")"
Get-Process | Where-Object {$_.Path -notmatch $regex}

所以现在匹配的正则表达式字符串是" ^(C:\ Windows | C:\ Program \ Files | C:\ Program \ Files \(x86))"