Powershell Subinacl.exe 双倍行距输出,无法捕获摘要信息(统计信息)
Powershell Subinacl.exe Double-Spaced Output, inability to capture summary information (statistics)
我尝试在远程机器上 运行 以下脚本,从第一行我得到正常输出,"Command was successful" 或类似的东西。对于第二个,它似乎可以工作,但是输出是间隔的并且不是完整的,好像缺少 4 行输出。
# This works as expected.
$output = Invoke-Command -ComputerName ServerName -ScriptBlock {auditpol /set /subcategory:"Registry" /success:enable /failure:enable}
# This creates double-spaced output and is missing the last 3 output lines.
$output = Invoke-Command -ComputerName ServerName -ScriptBlock {Subinacl.exe /verbose=1 /keyreg "HKEY_LOCAL_MACHINE\SYSTEM\Path" /sallowdeny="everyone"=SCD}
我想要第二行代码的输出:
SYSTEM\Path : delete Audit ACE 0 \everyone
SYSTEM\Path : new ace for \everyone
HKEY_LOCAL_MACHINE\SYSTEM\Path : 2 change(s)
Elapsed Time: 00 00:00:00
Done: 1, Modified 1, Failed 0, Syntax errors 0
Last Done : HKEY_LOCAL_MACHINE\SYSTEM\Path
但我得到的是:
S Y S T E M \ P a t h : d e l e t e A u d i t A C E 0 \ e v e r y o n e
S Y S T E M \ P a t h : n e w a c e f o r \ e v e r y o n e
H K E Y _ L O C A L _ M A C H I N E \ S Y S T E M \ P a t h : 2 c h a n g e ( s )
没有我想看的最后三行。我尝试将输出编码更改为 Unicode 或 UTF8,但无法正常工作。还有其他解决方案吗?
这些工具通常不会 return 正确的对象,因此您的字符串输出在后面。
您可以采用与默认不同的方式处理该输出和/或解析字符串 return 以获得您想要的格式。使用字符串 cmdlets...
Get-Command -Name '*string*' | Format-Table -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
Function ConvertFrom-SddlString 3.1.0.0 Microsoft.PowerShell.Utility
...
Function Format-String 1.3.6 PowerShellCookbook
...
Cmdlet ConvertFrom-String 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet ConvertFrom-StringData 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet Convert-String 3.1.0.0 Microsoft.PowerShell.Utility
...
Cmdlet Out-String 3.1.0.0 Microsoft.PowerShell.Utility
...
由于 Subinacl 用于显示或修改文件和文件夹权限、所有权和域的访问控制条目 (ACE),这与本机 cmdlet 相同...
Get-Command -Name '*acl*' | Format-Table -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
...
Cmdlet Get-Acl 3.0.0.0 Microsoft.PowerShell.Security
...
Cmdlet Set-Acl 3.0.0.0 Microsoft.PowerShell.Security
...
Application cacls.exe 10.0.17134.1 C:\WINDOWS\system32\cacls.exe
Application icacls.exe 10.0.17134.1 C:\WINDOWS\system32\icacls.exe
...
...提供。为什么不直接使用它们,因为它们 return 与 Subinacl 相比是合适的对象?
至于编码。
你是说,你尝试了这个讨论的答案,但它对你不起作用?
#set output encoding to unicode
[Console]::OutputEncoding = [Text.Encoding]::Unicode
$func_filePath = "G:\test\func.txt"
#use subinacl
[string]$SubInACLCommand = @"
subinacl.exe /file "$func_filePath" /setowner="hostname\Administrators"
"@
Invoke-Expression $SubInACLCommand
#revert output encoding back to default
[Console]::OutputEncoding = [Text.Encoding]::Default
OP更新
使用 RegEx 在您这边进行清理。从字符串中删除双空格和空行。
('S Y S T E M \ P a t h : d e l e t e A u d i t A C E 0 \ e v e r y o n e
S Y S T E M \ P a t h : n e w a c e f o r \ e v e r y o n e
H K E Y _ L O C A L _ M A C H I N E \ S Y S T E M \ P a t h : 2 c h a n g e ( s )').replace(' ','|').Replace(' ','').Replace('|',' ') -creplace('(?m)^\s*\r?\n','')
# Results
SYSTEM\Path : delete Audit ACE 0 \everyone
SYSTEM\Path : new ace for \everyone
HKEY_LOCAL_MACHINE\SYSTEM\Path : 2 change(s)
OP更新
在你的机器上试试这个,看看完整的结果是否真的像你期望的那样返回。
$SubinaclResults = Invoke-Command -ComputerName ServerName -ScriptBlock {Subinacl.exe /verbose=1 /keyreg "HKEY_LOCAL_MACHINE\SYSTEM\Path" /sallowdeny="everyone"=SCD}
$SubinaclResults
如果以上确实带回了完整的结果集。我的最终建议是将其输出为远程计算机上的临时文件,然后使用 Get-Content 将其读回您的工作站。
有两个不相关的问题:
(a) subinacl.exe
生成 UTF-16LE 编码输出.
(b) 它的 默认 /statistic
选项似乎 直接写入控制台 ,绕过标准输出,因此 无法被捕获 - 或者至少不容易;如果你知道怎么做,请告诉我们。
- 因此,以
Elapsed: ...
开头的包含统计信息(摘要信息)的最后一行总是打印到控制台。
- 相关问题subinacl get full output被同样的问题提示。
如前所述,(a) 可以通过 通过 [Console]::OutputEncoding
[=18= 告诉 PowerShell 在从外部程序捕获输出时期望的字符编码来补救]
(b) 如果您确实想要 捕获 统计行,则无法补救;下一个最好的事情是 suppress 统计输出与 /nostatistic
一起,至少不会产生不需要的控制台输出(但是,显然,您根本不会获得这些信息)。
综合起来:
$output = Invoke-Command -ComputerName ServerName -ScriptBlock {
# Tell PowerShell what character encoding to expect in subinacl's output.
[Console]::OutputEncoding = [Text.Encoding]::Unicode # UTF-16LE
# Note the addition of /nostatistic to suppress the direct-to-console summary info.
Subinacl.exe /nostatistic /verbose=1 /keyreg "HKEY_LOCAL_MACHINE\SYSTEM\Path" /sallowdeny="everyone"=SCD
}
注意:通常,您随后会恢复 [Console]::OutputEncoding
的先前值,但由于运行脚本块的远程计算机上的会话随后立即结束,因此它不是这里没有必要。
我尝试在远程机器上 运行 以下脚本,从第一行我得到正常输出,"Command was successful" 或类似的东西。对于第二个,它似乎可以工作,但是输出是间隔的并且不是完整的,好像缺少 4 行输出。
# This works as expected.
$output = Invoke-Command -ComputerName ServerName -ScriptBlock {auditpol /set /subcategory:"Registry" /success:enable /failure:enable}
# This creates double-spaced output and is missing the last 3 output lines.
$output = Invoke-Command -ComputerName ServerName -ScriptBlock {Subinacl.exe /verbose=1 /keyreg "HKEY_LOCAL_MACHINE\SYSTEM\Path" /sallowdeny="everyone"=SCD}
我想要第二行代码的输出:
SYSTEM\Path : delete Audit ACE 0 \everyone
SYSTEM\Path : new ace for \everyone
HKEY_LOCAL_MACHINE\SYSTEM\Path : 2 change(s)
Elapsed Time: 00 00:00:00
Done: 1, Modified 1, Failed 0, Syntax errors 0
Last Done : HKEY_LOCAL_MACHINE\SYSTEM\Path
但我得到的是:
S Y S T E M \ P a t h : d e l e t e A u d i t A C E 0 \ e v e r y o n e
S Y S T E M \ P a t h : n e w a c e f o r \ e v e r y o n e
H K E Y _ L O C A L _ M A C H I N E \ S Y S T E M \ P a t h : 2 c h a n g e ( s )
没有我想看的最后三行。我尝试将输出编码更改为 Unicode 或 UTF8,但无法正常工作。还有其他解决方案吗?
这些工具通常不会 return 正确的对象,因此您的字符串输出在后面。
您可以采用与默认不同的方式处理该输出和/或解析字符串 return 以获得您想要的格式。使用字符串 cmdlets...
Get-Command -Name '*string*' | Format-Table -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
Function ConvertFrom-SddlString 3.1.0.0 Microsoft.PowerShell.Utility
...
Function Format-String 1.3.6 PowerShellCookbook
...
Cmdlet ConvertFrom-String 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet ConvertFrom-StringData 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet Convert-String 3.1.0.0 Microsoft.PowerShell.Utility
...
Cmdlet Out-String 3.1.0.0 Microsoft.PowerShell.Utility
...
由于 Subinacl 用于显示或修改文件和文件夹权限、所有权和域的访问控制条目 (ACE),这与本机 cmdlet 相同...
Get-Command -Name '*acl*' | Format-Table -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
...
Cmdlet Get-Acl 3.0.0.0 Microsoft.PowerShell.Security
...
Cmdlet Set-Acl 3.0.0.0 Microsoft.PowerShell.Security
...
Application cacls.exe 10.0.17134.1 C:\WINDOWS\system32\cacls.exe
Application icacls.exe 10.0.17134.1 C:\WINDOWS\system32\icacls.exe
...
...提供。为什么不直接使用它们,因为它们 return 与 Subinacl 相比是合适的对象?
至于编码。
你是说,你尝试了这个讨论的答案,但它对你不起作用?
#set output encoding to unicode
[Console]::OutputEncoding = [Text.Encoding]::Unicode
$func_filePath = "G:\test\func.txt"
#use subinacl
[string]$SubInACLCommand = @"
subinacl.exe /file "$func_filePath" /setowner="hostname\Administrators"
"@
Invoke-Expression $SubInACLCommand
#revert output encoding back to default
[Console]::OutputEncoding = [Text.Encoding]::Default
OP更新
使用 RegEx 在您这边进行清理。从字符串中删除双空格和空行。
('S Y S T E M \ P a t h : d e l e t e A u d i t A C E 0 \ e v e r y o n e
S Y S T E M \ P a t h : n e w a c e f o r \ e v e r y o n e
H K E Y _ L O C A L _ M A C H I N E \ S Y S T E M \ P a t h : 2 c h a n g e ( s )').replace(' ','|').Replace(' ','').Replace('|',' ') -creplace('(?m)^\s*\r?\n','')
# Results
SYSTEM\Path : delete Audit ACE 0 \everyone
SYSTEM\Path : new ace for \everyone
HKEY_LOCAL_MACHINE\SYSTEM\Path : 2 change(s)
OP更新
在你的机器上试试这个,看看完整的结果是否真的像你期望的那样返回。
$SubinaclResults = Invoke-Command -ComputerName ServerName -ScriptBlock {Subinacl.exe /verbose=1 /keyreg "HKEY_LOCAL_MACHINE\SYSTEM\Path" /sallowdeny="everyone"=SCD}
$SubinaclResults
如果以上确实带回了完整的结果集。我的最终建议是将其输出为远程计算机上的临时文件,然后使用 Get-Content 将其读回您的工作站。
有两个不相关的问题:
(a)
subinacl.exe
生成 UTF-16LE 编码输出.(b) 它的 默认
/statistic
选项似乎 直接写入控制台 ,绕过标准输出,因此 无法被捕获 - 或者至少不容易;如果你知道怎么做,请告诉我们。- 因此,以
Elapsed: ...
开头的包含统计信息(摘要信息)的最后一行总是打印到控制台。 - 相关问题subinacl get full output被同样的问题提示。
- 因此,以
(a) 可以通过 通过 [Console]::OutputEncoding
[=18= 告诉 PowerShell 在从外部程序捕获输出时期望的字符编码来补救]
(b) 如果您确实想要 捕获 统计行,则无法补救;下一个最好的事情是 suppress 统计输出与 /nostatistic
一起,至少不会产生不需要的控制台输出(但是,显然,您根本不会获得这些信息)。
综合起来:
$output = Invoke-Command -ComputerName ServerName -ScriptBlock {
# Tell PowerShell what character encoding to expect in subinacl's output.
[Console]::OutputEncoding = [Text.Encoding]::Unicode # UTF-16LE
# Note the addition of /nostatistic to suppress the direct-to-console summary info.
Subinacl.exe /nostatistic /verbose=1 /keyreg "HKEY_LOCAL_MACHINE\SYSTEM\Path" /sallowdeny="everyone"=SCD
}
注意:通常,您随后会恢复 [Console]::OutputEncoding
的先前值,但由于运行脚本块的远程计算机上的会话随后立即结束,因此它不是这里没有必要。