PowerShell 替换在我的脚本的最后一行不起作用
PowerShell replace doesn't work in the last line in my script
我使用 PSVersion 5.1.19041.1320.
我正在获取 Windows 服务的安全描述符,并试图为特定用户(在 [=43 的示例中)替换其中的访问权限(在本例中为 'TEST') =]).
我的大体逻辑是:
- 获取服务的安全描述符
- 提取 'D:' 和 'S:' 之间的部分(使用正则表达式 '(?<=D:)(.*)(?=S:)')
- 提取经过身份验证的用户 (AU) 的访问权限(使用正则表达式 '(([^()]*))' )
- 替换访问权限
- Assemble 3. 和 2. 回到新的安全描述符
示例:
$user = 'AU'
[string]$newAccessRights = 'TEST'
$sddl = sc.exe sdshow wuauserv | Where-Object {$_}
$dacl = [RegEx]::Matches($sddl,'(?<=D:)(.*)(?=S:)') | ForEach-Object {$_.Value}
$dacl = $dacl -replace ([RegEx]::Matches($dacl,"(\([^()]*\))") | Where-Object {$_.Value.split(';')[-1] -eq "${user})"} | ForEach-Object {$_.Value.split(';')[2]}), $newAccessRights
$sddl -replace ([RegEx]::Matches($sddl,"(?<=D:)(.*)(?=S:\()") | ForEach-Object {$_.Value}), $dacl
我的期望是安全描述符:
D:(A;;CCLCSWRPLORC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOSDRCWDWO;;;WD)
将替换为:
D:(A;;TEST;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOSDRCWDWO;;;WD)
但事实并非如此:
Example
我做错了什么?
为什么最后一个替换不起作用?
你可以使用
$sddl = $sddl -replace "(\((?:[^();]*;){2})\w+((?:;[^()]*)?;$user\))", "`$newAccessRights`"
参见regex demo。 详情:
(\((?:[^();]*;){2})
- 第 1 组 (</code>):一个 <code>(
字符,然后两次出现除 (
、[=15= 之外的任意零个或多个字符] 和 ;
后跟 ;
char
\w+
- 一个或多个单词字符(或者,[^;]*
匹配除 ;
字符以外的零个或多个字符,它也适用于此)
((?:;[^()]*)?;$user\))
- 第 2 组 (</code>):<code>;
的可选序列,然后是 (
和 [=15= 以外的任何零个或多个字符] 然后是 ;
、$user
变量和一个 )
字符。
注意:如果$user
没有特殊字符,则不需要Regex.Escape
。否则,逃避它,[regex]::Escape($user)
。如果 $newAccessRights
中有一个 $
字符后跟一个数字,您也需要将其转义 $newAccessRights.Replace('$', '$$')
(这可以在替换模式中使用它之前完成) .
我使用 PSVersion 5.1.19041.1320.
我正在获取 Windows 服务的安全描述符,并试图为特定用户(在 [=43 的示例中)替换其中的访问权限(在本例中为 'TEST') =]).
我的大体逻辑是:
- 获取服务的安全描述符
- 提取 'D:' 和 'S:' 之间的部分(使用正则表达式 '(?<=D:)(.*)(?=S:)')
- 提取经过身份验证的用户 (AU) 的访问权限(使用正则表达式 '(([^()]*))' )
- 替换访问权限
- Assemble 3. 和 2. 回到新的安全描述符
示例:
$user = 'AU'
[string]$newAccessRights = 'TEST'
$sddl = sc.exe sdshow wuauserv | Where-Object {$_}
$dacl = [RegEx]::Matches($sddl,'(?<=D:)(.*)(?=S:)') | ForEach-Object {$_.Value}
$dacl = $dacl -replace ([RegEx]::Matches($dacl,"(\([^()]*\))") | Where-Object {$_.Value.split(';')[-1] -eq "${user})"} | ForEach-Object {$_.Value.split(';')[2]}), $newAccessRights
$sddl -replace ([RegEx]::Matches($sddl,"(?<=D:)(.*)(?=S:\()") | ForEach-Object {$_.Value}), $dacl
我的期望是安全描述符:
D:(A;;CCLCSWRPLORC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOSDRCWDWO;;;WD)
将替换为:
D:(A;;TEST;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOSDRCWDWO;;;WD)
但事实并非如此: Example
我做错了什么? 为什么最后一个替换不起作用?
你可以使用
$sddl = $sddl -replace "(\((?:[^();]*;){2})\w+((?:;[^()]*)?;$user\))", "`$newAccessRights`"
参见regex demo。 详情:
(\((?:[^();]*;){2})
- 第 1 组 (</code>):一个 <code>(
字符,然后两次出现除(
、[=15= 之外的任意零个或多个字符] 和;
后跟;
char\w+
- 一个或多个单词字符(或者,[^;]*
匹配除;
字符以外的零个或多个字符,它也适用于此)((?:;[^()]*)?;$user\))
- 第 2 组 (</code>):<code>;
的可选序列,然后是(
和 [=15= 以外的任何零个或多个字符] 然后是;
、$user
变量和一个)
字符。
注意:如果$user
没有特殊字符,则不需要Regex.Escape
。否则,逃避它,[regex]::Escape($user)
。如果 $newAccessRights
中有一个 $
字符后跟一个数字,您也需要将其转义 $newAccessRights.Replace('$', '$$')
(这可以在替换模式中使用它之前完成) .