Log Smuggler

Anyone who Administers Workspace ONE would know the massive black hole that is logging. There are some, but its quite limited in what it returns back to UEM for consumption.

This is where Log Smuggler comes in.

What is Log Smuggler?

It is exactly what the same says, a script that is executed to “Smuggle” logs in Workspace ONE’s log collection process.

How does it work?

Log Smuggler is a three part process, unfortunately.

The first is a native package with a powershell script in it, the script is written to capture the logs we want, zip it up, and place it in the appropiate folder. More on that in a sec.

The second is basically running the Hub Device logs.

You give it time to run, then you can grab the logs from the attachments area.
I showed this to the guys at VMware and they loved it so much they had the file upload limit raised from 5MB to 20MB, which was awesome of them. Thanks guys.

Powershell goodness!

Ok on to the script that does the work, you can pretty much put what you want in here to capture from the remote system. Eventlogs, patching logs, random whatever logs.





So all we have done above is just some general setup, where we are going to stick the logs temporarily.

########################### Airwatch Registry Install Logs
## Setup Log Paths
$machineLogPath="$destinationFolder\WS1AppDeploymentLogs\System"
if(!(Test-Path $machineLogPath))
    {
    New-Item -Path $machineLogPath -ItemType Directory | Out-Null
    }
$UserLogPath="$destinationFolder\WS1AppDeploymentLogs\User"
if(!(Test-Path $UserLogPath))
    {
    New-Item -Path $UserLogPath -ItemType Directory | Out-Null
    }

## Extract Machine Install Logs
$apps=Get-ChildItem "HKLM:\SOFTWARE\AirWatchMDM\AppDeploymentAgent\S-1-5-18"
foreach ($a in $apps)
    {
    $properties=Get-ItemProperty $a.PSPath
    $Logfile="$machineLogPath\" + $properties.Name +"-"+$properties.version+"-mdm.log"
    "Application: " + $properties.Name | out-file $Logfile -Force
    "Version: " + $properties.Version |out-file $Logfile -Append
    "Last Error Description: "+ $properties.LastErrorDesc|out-file $Logfile -Append
    "Last Error HRESULT: " + $properties.LastErrorHRESULT|out-file $Logfile -Append
    "Last Status Code: " + $properties.LastStatusCode|out-file $Logfile -Append
    "Dependencies: " + $properties.ReferencedDependencies|out-file $Logfile -Append
    "Is installed: " + $properties.IsInstalled|out-file $Logfile -Append
    "==================================================================================="|out-file $Logfile -Append
    $properties.LastDeploymentLog |Out-File $Logfile -append
    }

## Extract User Install Logs
$AirWatchKeys=Get-ChildItem "HKLM:\SOFTWARE\AirWatchMDM\AppDeploymentAgent"
$userKey=$AirWatchKeys.name -like "S-1-12-1-*"

foreach($key in $AirWatchKeys)
    {
    $k=$key.name -split "\\"
    if ($k[4] -like "S-1-12-1-*")
        {
        $userkey=$k[4]
        }
    }

$apps=Get-ChildItem "HKLM:\SOFTWARE\AirWatchMDM\AppDeploymentAgent\$userKey"
foreach ($a in $apps)
    {
    $properties=Get-ItemProperty $a.PSPath
    $Logfile="$UserLogPath\" + $properties.Name +"-"+$properties.version+"-mdm.log"
    "Application: " + $properties.Name | out-file $Logfile -Force
    "Version: " + $properties.Version |out-file $Logfile -Append
    "Last Error Description: "+ $properties.LastErrorDesc|out-file $Logfile -Append
    "Last Error HRESULT: " + $properties.LastErrorHRESULT|out-file $Logfile -Append
    "Last Status Code: " + $properties.LastStatusCode|out-file $Logfile -Append
    "Dependencies: " + $properties.ReferencedDependencies|out-file $Logfile -Append
    "Is installed: " + $properties.IsInstalled|out-file $Logfile -Append
    "==================================================================================="|out-file $Logfile -Append
    $properties.LastDeploymentLog |Out-File $Logfile -append
    }

Why VMware decided to put app install logs in to the registry will always be a mystery, but the above snippet extracts those logs in to something more usable.

##########################Applocker rules
## Setup Log Paths
$applockereLogPath="$destinationFolder\Applocker"

if(!(Test-Path $applockereLogPath))
    {
    New-Item -Path $applockereLogPath -ItemType Directory 
    }

wevtutil.exe epl "Microsoft-Windows-AppLocker/EXE and DLL" /q:"*[System[TimeCreated[timediff(@SystemTime) <= $eventLogTimeFilter]]]" "$applockereLogPath\Applocker_exe_and_dll.evtx"
wevtutil.exe epl "Microsoft-Windows-AppLocker/MSI and Script" /q:"*[System[TimeCreated[timediff(@SystemTime) <= $eventLogTimeFilter]]]" "$applockereLogPath\Applocker_MSI_and_Script.evtx"
wevtutil.exe epl "Microsoft-Windows-AppLocker/Packaged app-Deployment" /q:"*[System[TimeCreated[timediff(@SystemTime) <= $eventLogTimeFilter]]]" "$applockereLogPath\Applocker_Packaged_App_Deployment.evtx"
wevtutil.exe epl "Microsoft-Windows-AppLocker/Packaged app-Execution" /q:"*[System[TimeCreated[timediff(@SystemTime) <= $eventLogTimeFilter]]]" "$applockereLogPath\Applocker_Packaged_App_Execution.evtx"

Microsoft Applocker eventlogs. Handy since there is no easy way to centrally manage them in the first place.

#######################Application Event Log
wevtutil epl Application /q:"*[System[TimeCreated[timediff(@SystemTime) <= $eventLogTimeFilter]]]" "$destinationFolder\Application.evtx"

#######################SecurityEvent Log
wevtutil.exe epl Security "$destinationFolder\Security.evtx"

#######################System Event Log
wevtutil.exe epl System /q:"*[System[TimeCreated[timediff(@SystemTime) <= $eventLogTimeFilter]]]" "$destinationFolder\System.evtx"

#######################Setup Event Log
wevtutil.exe epl Setup /q:"*[System[TimeCreated[timediff(@SystemTime) <= $eventLogTimeFilter]]]" "$destinationFolder\Setup.evtx"

Your bog stock standard eventlogs. Huzzah.

############################Systeminfo
systeminfo.exe |out-file "$destinationFolder\Systeminfo.log"

Systeminfo has some handy… well.. info.

Things like Last boot time, OS install date, Hardware info, timezones etc….

#######################OMA-DM Event Logs
wevtutil.exe epl Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Admin "$destinationFolder\Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider-Admin.evtx"
wevtutil.exe epl Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Operational "$destinationFolder\Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider-Operational.evtx"

####################Registry Items for Oma-Dm
reg export HKLM\SOFTWARE\Microsoft\EnterpriseDesktopAppManagement $destinationFolder\EnterpriseDesktopAppManagement.reg
reg export HKLM\SOFTWARE\Microsoft\Enrollments $destinationFolder\Enrollments.reg
reg export HKLM\SOFTWARE\Microsoft\Provisioning\OMADM $destinationFolder\OMADM.reg

These are an important log for modern management, and are great for troubleshooting issues with Profiles, especially custom CSP’s.

#################################Running Processes
get-process -IncludeUserName |Format-Table -AutoSize | out-file "$destinationfolder\proceses.log"

#################################Running services
Get-service | Format-Table -AutoSize| out-file "$destinationfolder\services.log"

#################################Scheduled tasks
schtasks /query | out-file "$destinationFolder\ScheduledTasks.log"

#################################Local Admin Group Members
Get-LocalGroupMember administrators | Out-File "$destinationFolder\LocalAdmins.log"

#################################Devices
Get-PnpDevice | Format-Table -AutoSize | out-file "$destinationFolder\devices.log"

The comments speak for themselves, but handy info to have when troubleshooting.

#################################Windows Update Information
$x=Get-WindowsUpdateLog -LogPath "$destinationFolder\WindowsUpdates.Log" | Out-Null
Copy-Item -Path C:\windows\logs\cbs\CBS.log $destinationFolder
Copy-Item -Path C:\Windows\Logs\CBS\CBSPersist*.log $destinationFolder

Microsoft freaking updates. The bane of any IT admins existance. Logs that are handy for troubleshooting this mess.

################################# Firewall Logs
$firewallLogPath="$destinationFolder\Firewall"

if(!(Test-Path $firewallLogPath))
    {
    New-Item -Path $firewallLogPath -ItemType Directory | Out-Null
    }

Get-NetFirewallRule -Direction Inbound -Enabled True | Export-Csv "$firewallLogPath\InboundEnabledRules.csv"
Get-NetFirewallRule -Direction Outbound -Enabled True | Export-Csv "$firewallLogPath\OutboundEnabledRules.csv"
Get-NetFirewallRule |Export-Csv "$firewallLogPath\AllRules.csv"

####################Dism Log
Copy-Item -path C:\Windows\Logs\DISM\dism.log $destinationFolder

####################Network WLAN Report
Start-Process -FilePath netsh -ArgumentList "wlan show wlanreport" -Wait -NoNewWindow
$zip=Compress-Archive -Path C:\ProgramData\Microsoft\Windows\WlanReport -DestinationPath "$destinationFolder\Wlan-Report.zip" -CompressionLevel Optimal -Force

#Get Installed Apps
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Export-Csv $destinationFolder\InstalledApps64.csv -NoTypeInformation
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Export-Csv $destinationFolder\InstalledApps32.csv -NoTypeInformation

#Windows store logging
wevtutil.exe epl Microsoft-Windows-Store/Operational  "$destinationFolder\WindowsStore.evtx"
Wevtutil.exe epl Microsoft-Windows-AppXDeployment/Operational "$destinationFolder\AppXDeployment.evtx"
wevtutil.exe epl Microsoft-Windows-AppXDeploymentServer/Operational "$destinationFolder\AppXDeployment-Server-Operational.evtx"
wevtutil.exe epl Microsoft-Windows-TWinUI/Operational  "$destinationFolder\Microsoft-Windows-TwinUI-Operational.evtx"

More logs. Grab what you need, add what you want. Chuck out what you don’t want. Its flexible, I just find having too much is better than not enough.

############################Zip it up
$zip=Compress-Archive -Path "$destinationFolder\*" -DestinationPath "C:\ProgramData\Airwatch\UnifiedAgent\Logs\DigitalWorkplaceLogs.zip" -CompressionLevel Optimal -force | out-null

Remove-Item $destinationFolder -Force -Recurse  | Out-Null

And finally the Zipping and the shoving of the zip in to c:\ProgramData\Airwatch\UnifiedAgent\Logs, all ready to be grabbed by the log collection task.

Please remember this is just an example of what you can grab, excuse my coding, it could be done better but time is at a premium when you are rolling out a new platform in a short time period.


The Native Package

I’m not going to go in to how to create a package in UEM, there are good docos on the VMware docs website that cover the topic.

What I will go in to is how to get around some of the limitations. Chief one being, you cannot rerun a successfully run package.

I find this to be a major limitation, and one that I’ve raised via the feature request portal, as well as in direct meetings with VMware, however this isn’t a whinefest so to the workaround!

Set the package to always fail. Yup, its that easy. I’ve set the retry to 0, timeout to 5 minutes and the “When to Call Install Complete” criteria to rubbish.

The ending

And that is pretty much all there is to it.

This opens up a world of possibilities as far as getting information out of a managed Windows 10 box.

Comment below if there are other logs you’ve added, or anything else really.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.