From 7492d6a22ebf4aaa4516d1cd3704e97b8104c4d0 Mon Sep 17 00:00:00 2001 From: Throdne Date: Fri, 3 Jan 2025 20:56:26 +0000 Subject: [PATCH] Upload files to "Logging" --- Logging/README.md | 68 +++++++++++++++++++++++++ Logging/UnzipSpannedLogFiles.ps1 | 85 ++++++++++++++++++++++++++++++++ Logging/Write-Log.ps1 | 68 +++++++++++++++++++++++++ Logging/Write-Log.sh | 1 + 4 files changed, 222 insertions(+) create mode 100644 Logging/README.md create mode 100644 Logging/UnzipSpannedLogFiles.ps1 create mode 100644 Logging/Write-Log.ps1 create mode 100644 Logging/Write-Log.sh diff --git a/Logging/README.md b/Logging/README.md new file mode 100644 index 0000000..70fedbb --- /dev/null +++ b/Logging/README.md @@ -0,0 +1,68 @@ +# Workspace ONE Logging Function + +This PowerShell script provides a logging function to enable local log collection for any Workspace ONE (WS1) sensor or script. + +## Description + +The logging function allows you to log messages with different severity levels (Info, Warning, Error, Debug) and saves them to a specified log file. + +## Function Overview + +### `Write-Log` + +- **Parameters**: + - `-Message` (Mandatory): The log message to be recorded. + - `-LogLevel` (Mandatory): The level of the log message. Options are `Info`, `Warning`, `Error`, `Debug`. + +### `Manage-LogFile` +- **Parameters**: + - `-baseLogFileName` (Mandatory): The base log file name + - `-LogFilePath` (Mandatory): The log file location + - `-maxSizeMB` (Mandatory): the max log file size in MB + - `-maxFiles` (Mandatory): Maximum number of rotated log files + +### Example Usage + +```powershell +# Example usage +### Main Script ### +$baseLogFileName = "example" # Set the base log file name +$LogFilePath = "$env:ProgramData\Airwatch\UnifiedAgent\Logs" +$maxSizeMB = 5 # Maximum log file size in MB +$maxSizeBytes = $maxSizeMB * 1MB +$maxFiles = 4 # Maximum number of rotated log files + +Manage-LogFile -baseLogFileName $baseLogFileName -logFilePath $LogFilePath -maxSizeBytes $maxSizeBytes -maxFiles $maxFiles + +Write-Log -LogLevel "Info" -Message "Starting Script" +# Continue with the rest of your script... +``` + +# Unzip Spanned Log File +Unzip spanned log files downloaded from Workspace One UEM admin console. + +## Collect and Downlaod Logs from WS1 UEM + +1. **Start the collection for device logs via the WS1 UEM Console**: + - Navigate to the Workspace ONE UEM admin console. + - Go to `Devices > Select a device > More Actions > Request Device Log`. + - Make sure to select "HUB" logs + +2. **Download Device Logs**: + - Navigate to `Devices > Select the same device > More > Shred Device Logs`. + - Download the spanned `.zip` files. WS1 separates the logs into parts; there might be more than one file. + +## Example Execution: + +1. To run the script with default parameters: + ```powershell + .\UnzipSpannedLogFiles.ps1 + ``` +2. To specify a custom path for the 7-Zip executable: + ```powershell + .\UnzipSpannedLogFiles.ps1 -7zipPath "C:\CustomPathTo7zip\7z.exe" + ``` +3. To run the script and keep the original zipped files after extraction: + ```powershell + .\UnzipSpannedLogFiles.ps1 -keep + ``` diff --git a/Logging/UnzipSpannedLogFiles.ps1 b/Logging/UnzipSpannedLogFiles.ps1 new file mode 100644 index 0000000..9e98021 --- /dev/null +++ b/Logging/UnzipSpannedLogFiles.ps1 @@ -0,0 +1,85 @@ +<# +Author: Jerico Thomas +Date Updated: 2024-10-07 +Description: Unzip spanned log files from Workspace One admin console. +Version: 1.1 +Dependencies: 7-Zip + +Parameters: + - 7zipPath: (string) Path to the 7-Zip executable (default: "C:\Program Files\7-Zip\7z.exe") + - Keep: (switch) If specified, keep original zipped files after extraction. + +Generate Device Logs: +1. Navigate to the Workspace One admin console. +2. Go to Devices > Select a device > More Actions > Request Device Log. + +Download Device Logs: +1. Navigate to Devices > Select the same device > More > Shred Device Logs. +2. Download the spanned.zip files (each part is 10MB). + +Script Guide: +1. Download the spanned.zip files from the Workspace One admin console. +2. Create an empty folder and place the spanned.zip files in it. +3. Place this script in the same folder as the spanned.zip files. +4. Run the script. +5. The script extracts the spanned.zip files and cleans up the folder, leaving only the extracted files. + +Example Execution: +1. To run the script with default parameters: + ```powershell + .\UnzipSpannedLogFiles.ps1 + ``` +2. To specify a custom path for the 7-Zip executable: + ```powershell + .\UnzipSpannedLogFiles.ps1 -7zipPath "C:\CustomPathTo7zip\7z.exe" + ``` +3. To run the script and keep the original zipped files after extraction: + ```powershell + .\UnzipSpannedLogFiles.ps1 -keep + ``` +#> + +param ( + [string]$7zipPath = "C:\Program Files\7-Zip\7z.exe", + [switch]$Keep = $false +) + +# Check if 7-Zip is installed +if (!(Test-Path -Path $7zipPath)) { + Write-Output "7-Zip not found at '$7zipPath'. Please install 7-Zip." + exit 1 +} + +# Remove .zip extension from any files that have spanned.zxx.zip in the name +Get-ChildItem -Filter "*spanned.*.zip" | Rename-Item -NewName { $_.Name -replace '\.zip$', '' } -ErrorAction Stop + +# Extract spanned zip files +$zipFile = Get-ChildItem -Filter "*spanned.zip" +if ($zipFile) { + & $7zipPath x $zipFile.FullName -oSpannedFiles -y + + # Find all .zip files in the output directory recursively + $innerZipFiles = Get-ChildItem -Path SpannedFiles -Filter "*.zip" -Recurse -ErrorAction Stop + + # Extract all inner zip files + foreach ($file in $innerZipFiles) { + & $7zipPath x $file.FullName -y + } + + if (!$Keep) { + # Create Archived folder if it doesn't exist + if (!(Test-Path -Path $archiveDir)) { + New-Item -ItemType Directory -Path $archiveDir -ErrorAction Stop + } + # Move original zip files to the Archived folder + Get-ChildItem -Filter "*spanned.*" | Move-Item -Destination $archiveDir -ErrorAction Stop + # Remove the SpannedFiles directory + Remove-Item -Path SpannedFiles -Recurse -Force -ErrorAction Stop + Remove-Item -Path Archived -Recurse -Force -ErrorAction Stop + } +} +else { + Write-Output "No spanned zip files found." +} + +exit 0 diff --git a/Logging/Write-Log.ps1 b/Logging/Write-Log.ps1 new file mode 100644 index 0000000..be7fe39 --- /dev/null +++ b/Logging/Write-Log.ps1 @@ -0,0 +1,68 @@ +function Manage-LogFile { + param ( + [string]$baseLogFileName, + [string]$logFilePath, + [int]$maxSizeBytes, + [int]$maxFiles + ) + + $logFile = Join-Path $logFilePath "$baseLogFileName.log" + + # Check if the main log file exists + if (Test-Path $logFile) { + $logFileSize = (Get-Item $logFile).Length + + # Rotate logs if size exceeds the limit + if ($logFileSize -ge $maxSizeBytes) { + # Rotate existing log files + for ($i = $maxFiles; $i -ge 1; $i--) { + $oldLogFile = Join-Path $logFilePath "$($baseLogFileName)_$i.log" + if (Test-Path $oldLogFile) { + if ($i -eq $maxFiles) { + Remove-Item -Path $oldLogFile -Force + Write-Log -LogLevel "Info" -Message "Deleted oldest log file: $baseLogFileName_$i.log" + } else { + Rename-Item -Path $oldLogFile -NewName (Join-Path $logFilePath "$($baseLogFileName)_$($i + 1).log") -Force + } + } + } + Rename-Item -Path $logFile -NewName (Join-Path $logFilePath "$($baseLogFileName)_1.log") + Write-Log -LogLevel "Info" -Message "Log file rotated: $($baseLogFileName)_1.log" + } + } + # Delete old log files if exceeding the max count + $logFiles = Get-ChildItem -Path $logFilePath -Filter "$($baseLogFileName)_*.log" | Sort-Object LastWriteTime + if ($logFiles.Count -gt $maxFiles) { + $logFiles[0..($logFiles.Count - $maxFiles - 1)] | ForEach-Object { + Remove-Item -Path $_.FullName -Force + Write-Log -LogLevel "Info" -Message "Deleted old log file: $($_.Name)" + } + } +} + +function Write-Log { + param ( + [Parameter(Mandatory = $true)] + [string]$Message, + + [Parameter(Mandatory = $true)] + [ValidateSet("Info", "Warning", "Error", "Debug")] + [string]$LogLevel + ) + + $formattedMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [$LogLevel] - $Message" + $formattedMessage | Out-File -FilePath (Join-Path $LogFilePath "$baseLogFileName.log") -Append -Encoding UTF8 +} + +# Example usage +### Main Script ### +$baseLogFileName = "example" # Set the base log file name +$LogFilePath = "$env:ProgramData\Airwatch\UnifiedAgent\Logs" +$maxSizeMB = 5 # Maximum log file size in MB +$maxSizeBytes = $maxSizeMB * 1MB +$maxFiles = 4 # Maximum number of rotated log files + +Manage-LogFile -baseLogFileName $baseLogFileName -logFilePath $LogFilePath -maxSizeBytes $maxSizeBytes -maxFiles $maxFiles + +Write-Log -LogLevel "Info" -Message "Starting Script" +# Continue with the rest of your script... diff --git a/Logging/Write-Log.sh b/Logging/Write-Log.sh new file mode 100644 index 0000000..83dd6eb --- /dev/null +++ b/Logging/Write-Log.sh @@ -0,0 +1 @@ +# Still need to write this function out for macOS.