Public/Invoke-VBWorkstationReport.ps1
|
# ============================================================ # FUNCTION : Invoke-VBWorkstationReport # MODULE : VB.WorkstationReport # VERSION : 1.3.0 # CHANGED : 14-04-2026 -- Standards compliance fixes # AUTHOR : Vibhu Bhatnagar # PURPOSE : Orchestrates workstation data collection and uploads reports to Nextcloud # ENCODING : UTF-8 with BOM # ============================================================ function Invoke-VBWorkstationReport { <# .SYNOPSIS Generates a full workstation report and uploads it to Nextcloud. .DESCRIPTION Invoke-VBWorkstationReport orchestrates the four data collection functions: - Get-VBUserPrinterMappings -> <COMPUTERNAME>_UPM.csv - Get-VBSyncCenterStatus -> <COMPUTERNAME>_CNC.csv - Get-VBUserFolderRedirections -> <COMPUTERNAME>_UFR.csv - Get-VBNetworkInterface -> <COMPUTERNAME>_NI.csv Each report is saved as a CSV to the local output path, then all CSVs are uploaded to the configured Nextcloud destination folder using Set-VBNextcloudFile. Existing CSVs in the output path are cleared before collection begins. Credentials are always passed as a PSCredential -- plain-text passwords are not accepted. .PARAMETER Credential PSCredential for Nextcloud authentication. Use Get-Credential or build a PSCredential from a SecureString. Required. .PARAMETER NextcloudBaseUrl Base URL of the Nextcloud instance. Defaults to 'https://vault.dediserve.com'. .PARAMETER NextcloudDestination Remote folder path where reports will be uploaded. Defaults to 'Vibhu/Reports'. .PARAMETER OutputPath Local folder path where CSV reports are written before upload. Defaults to 'C:\Realtime'. The folder is created if it does not exist. .PARAMETER SkipUpload When specified, reports are generated and saved locally but not uploaded to Nextcloud. Useful for testing or when Nextcloud is unavailable. .EXAMPLE $cred = Get-Credential Invoke-VBWorkstationReport -Credential $cred Runs the full report against the local machine with default paths and uploads to Nextcloud. .EXAMPLE $secPw = ConvertTo-SecureString 'MyAppPassword' -AsPlainText -Force $cred = New-Object PSCredential('myuser', $secPw) Invoke-VBWorkstationReport -Credential $cred ` -NextcloudBaseUrl 'https://cloud.example.com' ` -NextcloudDestination 'IT/Workstations' ` -OutputPath 'D:\Reports' Generates reports to D:\Reports and uploads to a custom Nextcloud path. .EXAMPLE Invoke-VBWorkstationReport -Credential $cred -SkipUpload -OutputPath 'C:\Temp\Reports' Generates reports locally without uploading -- useful for offline testing. .OUTPUTS PSCustomObject Returns a summary object with: - ComputerName : Machine the report was collected from - OutputPath : Local folder where CSVs were written - ReportsGenerated: Number of CSV files successfully created - UploadResults : Array of upload result objects (empty when -SkipUpload is used) - Duration : Total execution time - Status : 'Success', 'PartialFailure', or 'Failed' - CollectionTime : Timestamp of the run .NOTES Version : 1.3.0 Author : Vibhu Bhatnagar Category: Windows Workstation Administration Requirements: - PowerShell 5.1 or higher - Administrative privileges (for registry hive access) - Network access to Nextcloud (unless -SkipUpload is specified) - WorkstationReport module functions must be loaded Security note: Never store credentials in plain text inside scripts. Use Get-Credential interactively, or retrieve credentials from a secrets manager / encrypted credential store. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [PSCredential]$Credential, [ValidateNotNullOrEmpty()] [string]$NextcloudBaseUrl = 'https://vault.dediserve.com', [ValidateNotNullOrEmpty()] [string]$NextcloudDestination = 'Vibhu/Reports', [ValidateNotNullOrEmpty()] [string]$OutputPath = 'C:\Realtime', [switch]$SkipUpload ) $startTime = Get-Date $collectionTime = $startTime.ToString('dd-MM-yyyy HH:mm:ss') $computerName = $env:COMPUTERNAME $csvFiles = [System.Collections.Generic.List[string]]::new() $errors = [System.Collections.Generic.List[string]]::new() try { # Ensure output directory exists if (-not (Test-Path $OutputPath)) { Write-Verbose "Creating output directory: $OutputPath" $null = New-Item -Path $OutputPath -ItemType Directory -Force } # Clear previous reports Write-Verbose "Clearing existing CSVs from: $OutputPath" Remove-Item -Path (Join-Path $OutputPath '*.csv') -Force -ErrorAction SilentlyContinue # -- Report 1: User Printer Mappings ----------------------------------------- $csvPath = Join-Path $OutputPath "${computerName}_UPM.csv" Write-Verbose "Collecting printer mappings..." try { Get-VBUserPrinterMappings -TableOutput | Export-Csv -Path $csvPath -NoTypeInformation -Force $csvFiles.Add($csvPath) Write-Verbose "Saved: $csvPath" } catch { $errors.Add("UPM: $($_.Exception.Message)") Write-Warning "Printer mapping collection failed: $($_.Exception.Message)" } # -- Report 2: Sync Center Status --------------------------------------------- $csvPath = Join-Path $OutputPath "${computerName}_CNC.csv" Write-Verbose "Collecting Sync Center status..." try { Get-VBSyncCenterStatus | Export-Csv -Path $csvPath -NoTypeInformation -Force $csvFiles.Add($csvPath) Write-Verbose "Saved: $csvPath" } catch { $errors.Add("CNC: $($_.Exception.Message)") Write-Warning "Sync Center collection failed: $($_.Exception.Message)" } # -- Report 3: User Folder Redirections --------------------------------------- $csvPath = Join-Path $OutputPath "${computerName}_UFR.csv" Write-Verbose "Collecting folder redirections..." try { Get-VBUserFolderRedirections -TableOutput | Export-Csv -Path $csvPath -NoTypeInformation -Force $csvFiles.Add($csvPath) Write-Verbose "Saved: $csvPath" } catch { $errors.Add("UFR: $($_.Exception.Message)") Write-Warning "Folder redirection collection failed: $($_.Exception.Message)" } # -- Report 4: Network Interfaces --------------------------------------------- $csvPath = Join-Path $OutputPath "${computerName}_NI.csv" Write-Verbose "Collecting network interfaces..." try { Get-VBNetworkInterface | Export-Csv -Path $csvPath -NoTypeInformation -Force $csvFiles.Add($csvPath) Write-Verbose "Saved: $csvPath" } catch { $errors.Add("NI: $($_.Exception.Message)") Write-Warning "Network interface collection failed: $($_.Exception.Message)" } # -- Upload -------------------------------------------------------------------- $uploadResults = @() if (-not $SkipUpload -and $csvFiles.Count -gt 0) { Write-Verbose "Uploading $($csvFiles.Count) file(s) to $NextcloudBaseUrl/$NextcloudDestination" $uploadResults = $csvFiles | Set-VBNextcloudFile -BaseUrl $NextcloudBaseUrl ` -Credential $Credential -DestinationPath $NextcloudDestination -Overwrite $failedUploads = @($uploadResults | Where-Object { $_.Status -eq 'Failed' }) if ($failedUploads.Count -gt 0) { $failedUploads | ForEach-Object { $errors.Add("Upload failed for $($_.SourceFile): $($_.Error)") Write-Warning "Upload failed: $($_.SourceFile) -- $($_.Error)" } } } elseif ($SkipUpload) { Write-Verbose 'Upload skipped (-SkipUpload specified).' } $duration = (Get-Date) - $startTime $statusCode = if ($errors.Count -eq 0) { 'Success' } elseif ($csvFiles.Count -gt 0) { 'PartialFailure' } else { 'Failed' } [PSCustomObject]@{ ComputerName = $computerName OutputPath = $OutputPath ReportsGenerated = $csvFiles.Count UploadResults = $uploadResults Errors = if ($errors.Count) { $errors -join '; ' } else { $null } Duration = '{0:mm\:ss\.fff}' -f $duration Status = $statusCode CollectionTime = $collectionTime } } catch { Write-Error -Message "Invoke-VBWorkstationReport failed: $($_.Exception.Message)" [PSCustomObject]@{ ComputerName = $computerName OutputPath = $OutputPath ReportsGenerated = $csvFiles.Count UploadResults = @() Errors = $_.Exception.Message Duration = '{0:mm\:ss\.fff}' -f ((Get-Date) - $startTime) Status = 'Failed' CollectionTime = $collectionTime } } } |