Created
May 25, 2018 10:00
-
-
Save mwallner/d3c86794bb74680b0c0cf4e9a9758ab4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://mwallner.net/2017/10/06/powershell-logging-made-easy-thinking-raii/ | |
function Monitor { | |
param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True)] | |
[scriptblock]$scriptblk, | |
[Parameter(Mandatory = $True)] | |
[string]$Description, | |
[Parameter(Mandatory = $False)] | |
[scriptblock]$ResultReceiver, | |
[Parameter(Mandatory = $False)] | |
[switch]$CanFail | |
) | |
$_start = Get-Date | |
$_ex = $null | |
$_res = 0 | |
try { | |
& $scriptblk | |
$res = $lastexitcode | |
} | |
catch { | |
$_ex = $_ | |
$res = $lastexitcode | |
} | |
finally { | |
$_resobj = @{ | |
Exception = $_ex | |
Result = $_res | |
Description = $Description | |
Duration = ($(Get-Date) - $_start) | |
} | |
if ($ResultReceiver) { | |
$ResultReceiver.Invoke($_resobj) | |
} | |
if (-Not $CanFail -And $_ex) { | |
throw $_ex | |
} | |
} | |
} | |
function LogTiming { | |
param( | |
[Parameter(Mandatory = $True)] | |
[PSCustomObject]$logobj | |
) | |
Write-Host "* " -NoNewline | |
Write-Host $logobj.Duration -ForegroundColor Yellow -NoNewline | |
Write-Host " | " -NoNewline | |
Write-Host $logobj.Description -ForegroundColor Green | |
} | |
Write-Host "###############################################" | |
Write-Host "$(whoami) @ $(hostname)" | |
$PSVersionTable | Write-Output | |
Monitor -Description "Getting PS-Drives..." -ResultReceiver $function:LogTiming { | |
$(Get-PSDrive) | Out-Null | |
} | |
Write-Host "###############################################" | |
Write-Host "" | |
$cmd2Run = "Write-Output 'foo' | Out-Null" | |
#$cmd2Run = "Start-Sleep 0" | |
Monitor -Description "powershell.exe" -ResultReceiver $function:LogTiming { | |
powershell.exe $cmd2Run | Out-Null | |
} | |
Monitor -Description "powershell.exe from cmd.exe" -ResultReceiver $function:LogTiming { | |
cmd /c powershell.exe -NoProfile -ExecutionPolicy Bypass $cmd2Run | |
} | |
Monitor -Description "powershell.exe NoProfile" -ResultReceiver $function:LogTiming { | |
powershell.exe -NoProfile $cmd2Run | |
} | |
Monitor -Description "powershell.exe NoProfile from cmd.exe" -ResultReceiver $function:LogTiming { | |
cmd /c powershell.exe -NoProfile $cmd2Run | |
} | |
Monitor -Description "powershell.exe NoProfile Bypass ExecutionPolicy" -ResultReceiver $function:LogTiming { | |
powershell.exe -NoProfile -ExecutionPolicy Bypass $cmd2Run | |
} | |
Monitor -Description "powershell.exe NoProfile Bypass ExecutionPolicy from cmd.exe" -ResultReceiver $function:LogTiming { | |
cmd /c powershell.exe -NoProfile -ExecutionPolicy Bypass $cmd2Run | |
} | |
function callViaVB($cmd) { | |
$tmpFile = Join-Path $env:TEMP "perftest.vbs" | |
Remove-Item $tmpFile -Force -ErrorAction SilentlyContinue | |
$helperFile = @" | |
Dim cmd: cmd = "$($cmd.Replace("`"","`"`""))" | |
Dim wsh, wshProcessEnv, oExec | |
Set wsh = Wscript.CreateObject("WScript.Shell") | |
wscript.echo "Run <" & cmd & "> ..." | |
Set oExec = wsh.Exec(cmd) | |
do | |
WScript.Sleep(10) | |
wscript.echo oExec.StdOut.ReadAll | |
loop until oExec.Status = 1 ' WshFinished | |
if oExec.ExitCode <> 0 then | |
wscript.echo oExec.StdErr.ReadAll | |
end if | |
"@ | |
$helperFile | Out-File $tmpFile | |
cscript $tmpFile | Out-Null | |
Remove-Item $tmpFile -Force -ErrorAction SilentlyContinue | |
} | |
Monitor -Description "powershell.exe from vbs" -ResultReceiver $function:LogTiming { | |
callViaVB "powershell.exe `"$cmd2Run`"" | |
} | |
Monitor -Description "powershell.exe NoProfile from vbs" -ResultReceiver $function:LogTiming { | |
callViaVB "powershell.exe -NoProfile `"$cmd2Run`"" | |
} | |
Monitor -Description "powershell.exe NoProfile Bypass ExecutionPolicy from vbs" -ResultReceiver $function:LogTiming { | |
callViaVB "powershell.exe -NoProfile -ExecutionPolicy Bypass `"$cmd2Run`"" | |
} | |
Monitor -Description "powershell.exe from cmd.exe via vbs" -ResultReceiver $function:LogTiming { | |
callViaVB "cmd /c powershell.exe `"$cmd2Run`"" | |
} | |
Monitor -Description "powershell.exe NoProfile from cmd.exe via vbs" -ResultReceiver $function:LogTiming { | |
callViaVB "cmd /c powershell.exe -NoProfile `"$cmd2Run`"" | |
} | |
Monitor -Description "powershell.exe NoProfile Bypass ExecutionPolicy from cmd.exe via vbs" -ResultReceiver $function:LogTiming { | |
callViaVB "cmd /c powershell.exe -NoProfile -ExecutionPolicy Bypass `"$cmd2Run`"" | |
} | |
$tmpPerfPs1File = Join-Path $env:TEMP "perftest.ps1" | |
Remove-Item $tmpPerfPs1File -Force -ErrorAction SilentlyContinue | |
$cmd2Run | Out-File $tmpPerfPs1File | |
Monitor -Description "powershell.exe call script" -ResultReceiver $function:LogTiming { | |
powershell.exe $tmpPerfPs1File | Out-Null | |
} | |
Monitor -Description "powershell.exe NoProfile call script" -ResultReceiver $function:LogTiming { | |
powershell.exe -NoProfile $tmpPerfPs1File | Out-Null | |
} | |
Monitor -Description "powershell.exe Bypass ExecutionPolicy call script" -ResultReceiver $function:LogTiming { | |
powershell.exe -NoProfile -ExecutionPolicy Bypass $tmpPerfPs1File | Out-Null | |
} | |
Remove-Item $tmpPerfPs1File -Force -ErrorAction SilentlyContinue |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment