【问题标题】:Powershell Subinacl.exe Double-Spaced Output, inability to capture summary information (statistics)Powershell Subinacl.exe 双倍行距输出,无法捕获摘要信息(统计)
【发布时间】:2018-08-15 21:24:07
【问题描述】:

我尝试在远程机器上运行以下脚本,从第一行我得到正常输出,“命令成功”或类似的东西。对于第二个,它似乎可以正常工作,但输出间隔且不完整,缺少 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 )

没有我想看到的最后 3 行。我尝试将输出编码更改为 Unicode 或 UTF8,但不起作用。还有其他解决方案吗?

【问题讨论】:

  • 您正在为两个不同的用例运行两个不同的工具,听起来您期望得到相同的结果,但这并不是真的。请在此处定义/澄清您要查找的内容。含义,成功和错误,并确定您在返回结果中的具体目标。否则我们只能假设。
  • @postanote 是的,有两种不同的工具。第二个给我带来了一些麻烦,因为输出不清楚。我已经编辑了问题:)
  • "我尝试将输出编码更改为 Unicode 或 UTF8 但不起作用。" - 问题是将文本编码为双字节编码(例如 PowerShell 的“Unicode " 但不是 "UTF8"),然后将其作为单字节编码读回,因此双字节显示为 char、space、char、space 等。stackoverflow.com/questions/33630299/… 描述了它以及您尝试过的修复 - 但是你在哪一边做出改变?也许您需要在调用 SubInAcl 之前将它放在脚本块中?
  • 或者这里 social.technet.microsoft.com/Forums/ie/en-US/… 建议通过 cmd /c subinacl... 运行它
  • @TessellatingHeckler 有趣的是,我将 Unicode 行放在 ScriptBlock 中,输出不再间隔,但仍然缺少最后 3 行。我也尝试了 cmd /c 选项,但它似乎不起作用

标签: powershell character-encoding stdout subinacl


【解决方案1】:

两个不相关的问题

  • (a) subinacl.exe 产生 UTF-16LE 编码输出

  • (b) 它的默认开启/statistic 选项似乎直接写入控制台,绕过标准输出,因此无法捕获 - 或者至少不容易;如果你知道怎么做,请告诉我们。

    • 因此,以Elapsed: ... 开头的包含统计信息(摘要信息)的最后一行始终会打印到控制台。
    • 相关问题subinacl get full output是由同样的问题提示的。

(a) 如上所述,可以通过 通过[Console]::OutputEncoding

告诉 PowerShell 在从外部程序捕获输出时期望什么字符编码来补救

(b) 如果您确实想捕获统计行,则无法补救;下一个最好的办法是抑制/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 值,但由于运行脚本块的远程计算机上的会话随即结束,因此这里没有必要。支持>

【讨论】:

    【解决方案2】:

    这些工具通常不会返回正确的对象,因此您的字符串会在后面输出。

    您可以以不同于默认值的方式处理该输出和/或解析返回的字符串以获得您所追求的格式。使用字符串 cmdlet...

    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
    ... 
    

    ...提供。为什么不直接使用它们,因为它们返回正确的对象 vs Subinacl?

    至于编码。

    你是说,你从这个讨论中尝试了这个答案,但它对你不起作用?

    Double spacing of output from SubInACL called from PowerShell

    #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 将其读回您的工作站。

    【讨论】:

    • 是的,我尝试了这个答案,但没有奏效。输出很奇怪,当我在远程机器上运行脚本块代码时,输​​出很好,但是当我从本地机器运行脚本时,输出没有正确显示。
    • 好的,现在我怀疑这有点奇怪。但是,如果迫在眉睫,您可以恢复使用 RegEx 来清理您这边的输出。使用您发布的输出查看我的更新。
    • 正如上面其他用户建议的那样,我将 Unicode 行放入 ScriptBlock 并得到与您相同的输出,但仍然缺少最后 3 行
    • 您是否使用正则表达式示例得到相同的结果,这意味着缺少 3 行?多年来我没有在任何系统上使用或使用 Subinacl,因此在任何系统上都没有使用它来实际测试您所看到的。
    • 是的,我也试过正则表达式,但缺少三行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2012-11-25
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 2015-02-06
    相关资源
    最近更新 更多