Skip to content

Instantly share code, notes, and snippets.

@mwallner
Created May 25, 2018 10:00
Show Gist options
  • Save mwallner/d3c86794bb74680b0c0cf4e9a9758ab4 to your computer and use it in GitHub Desktop.
Save mwallner/d3c86794bb74680b0c0cf4e9a9758ab4 to your computer and use it in GitHub Desktop.
# 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