Search code examples
powershellcharacter-encodingstdoutsubinacl

Powershell Subinacl.exe Double-Spaced Output, inability to capture summary information (statistics)


I try to run the following script on a remote machine, from the first line I get the normal output, "Command was successful" or something like that. For the second one it seems that its working, but the output its spaced and its not full, there are like 4 lines of output missing.

# 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} 

I want this output for the second code line:

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

But instead I get:

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 )

Without the last 3 lines, which I want to see. I tried change the Output Encoding to Unicode or UTF8 but are not working. Any other solutions?


Solution

  • There are two unrelated problems:

    • (a) subinacl.exe produces UTF-16LE-encoded output.

    • (b) Its on-by-default /statistic option seems to write directly to the console, bypassing stdout, and therefore cannot be captured - or at least not easily; do tell us if you know how.

      • Therefore, the last block of lines containing statistics (summary information), which starts with Elapsed: ..., always prints to the console.
      • Related question subinacl get full output was prompted by the same problem.

    (a), as stated, can be remedied by telling PowerShell what character encoding to expect when capturing output from external programs, via [Console]::OutputEncoding

    (b) cannot be remedied if you do want to capture the statistics lines too; the next best thing is to suppress statistics output altogether with /nostatistic, which at least doesn't produce unwanted console output (but, obviously, you won't have the information at all).

    Putting it all together:

    $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
    } 
    

    Note: Normally, you'd restore the previous value of [Console]::OutputEncoding afterward, but since the session on the remote computer in which the script block runs ends right after, it isn't necessary here.