If you ever need to deploy an executable like Sysmon on one or more VMs on Azure and don’t have any configuration management in place…
These Powershell Script snippets will come to rescue!
This process doesn’t provide a best practise on how to deploy software in an environment but if your tools and resources are limited this will help you out.
Powershell Az module
The plan is to send a script to an Azure VM using the following command as found in the Powershell Az module
Invoke-AzVMRunCommand -CommandId ‘RunPowerShellScript’ -ScriptPath ‘script.ps1’ -Parameter @{param1 = “-Verbose”}
What will happen, the script we refer to will be uploaded to the VM.
Next the script will be executed.
The script itself would download and execute a Sysmon.exe.
function DownloadSysmon { | |
[cmdletbinding()] | |
Param() | |
$Result = $(Test-Path (Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath sysmon.exe)); | |
if(-not $Result) { | |
try { | |
# https://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename%28v=vs.110%29.aspx | |
$tmpfile = [System.IO.Path]::GetTempFileName() | |
$null = Invoke-WebRequest -Uri 'https://live.sysinternals.com/Sysmon.exe' ` | |
-OutFile $tmpfile -ErrorAction Stop | |
Write-Verbose 'Sucessfully downloaded Sysmon.exe' | |
Unblock-File -Path $tmpfile -ErrorAction Stop | |
$exefile = Join-Path -Path (Split-Path -Path $tmpfile -Parent) -ChildPath 'a.exe' | |
if (Test-Path $exefile) { | |
Remove-Item -Path $exefile -Force -ErrorAction Stop | |
} | |
$tmpfile | Rename-Item -NewName 'a.exe' -Force -ErrorAction Stop | |
} catch { | |
Write-Verbose "Something went wrong $($_.Exception.Message)" | |
} | |
} | |
} |
But this didn’t work out!
the command Invoke-Webrequest will result in “The underlying connection was closed: An unexpected error occurred on a send.”
Even though this machine normally could perform webrequests, from this session it doesn’t.
And there could also be a case where machines are isolated.
This approach is likely to fail.
Self extracting powershell script reversed
My next idea, we could convert a binary file into a string, put this string into a script file as a string variable together with scripting that would execute the opposite.
Let’s see what come of this.
1. read the contents of the file to a variable (Array of Bytes)
2. convert this Byte Array into a Base64 String
3. write string variable to a file
This file contains 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
$fileAsByteArray = [System.IO.File]::ReadAllBytes($FilePath); | |
$Base64String = [System.Convert]::ToBase64String($fileAsByteArray); | |
$Base64String | Out-File '.\a file' |
We wrap this file with scripting so the string will be loaded as a String variable and a function that will convert the string back to a byteArray and Write it to disk as an executable.
In the end we execute the executable.
This file contains 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
$sysmonAsString="H4sIAAAAAAAAC+y9f2BUxdU/vLvZJEtY…" | |
$ByteArray = [System.Convert]::FromBase64String($sysmonAsString) | |
[System.IO.File]::WriteAllBytes('.\Sysmon.exe', $ByteArray); | |
Start-Process –FilePath '.\Sysmon.exe' |
There are cases this could work, but we are working with Sysmon.exe, it contains over 3M of Bytes.
This will result in: “Internal server error”
Do not fear!
Back in the days of limited diskspace and 1,44MB High Density diskettes people invented compression.
The good thing is we can leverage this into our script.
The solution!
https://gist.github.com/MauRiEEZZZ/c2f3b4bb226f0ed9d421e7f6ad4857e9
After compression Sysmon is only 31% of it’s original size.
And now everything is small enough to be send and the installation goes great!
Like I said before this is not a typical good form of software deployment.
Problems arise when the configuration drifts from the desired state.
If we need to change the configuration we need to change that on all the affected machines one by one.
But that will be a whole other blog…