Public/AzStackHci.ClusterPerformance.ps1
|
# /////////////////////////////////////////////////////////////////// # Send-ClusterPerformanceHistory function # Used to collect and send cluster performance history to Microsoft. # Uses Get-SddcDiagnosticInfo and Send-DiagnosticInformation functions # /////////////////////////////////////////////////////////////////// function Send-ClusterPerformanceHistory { <# .SYNOPSIS Collects the SDDC diagnostic information, including the cluster performance history, and sends the diagnostic information to Microsoft. .DESCRIPTION This function collects the SDDC diagnostic information, including the cluster performance history, and sends the diagnostic information to Microsoft. The function requires the name of the cluster to collect the SDDC and Cluster Performance History. The function also requires the time frame for the performance history, the root path to store the output files. There is an optional switch to ignore disk space check for log collection and an optional switch to exclude cluster performance history from the diagnostic information. .PARAMETER ClusterName The name of the cluster to collect SDDC and Cluster Performance History. .PARAMETER PerformanceHistoryTimeFrame The time frame for the performance history. The default is LastDay. .PARAMETER OutputRootPath The root path to store the output files. The default is C:\Temp, if not specified. .PARAMETER IgnoreDiskSpaceCheck Optional switch, used to ignore disk space check for log collection. .PARAMETER ExcludeClusterPerformanceHistory Optional switch, to exclude cluster performance history from the diagnostic information. .EXAMPLE Send-ClusterPerformanceHistory -ClusterName "Cluster-01" -OutputRootPath "C:\Temp" This example collects the SDDC diagnostic information, including the cluster performance history, for the cluster named "Cluster-01". The performance history time frame defaults to "LastDay", as the parameter was not specified. The output files are stored in the "C:\Temp" folder. The disk space check is checked, to ensure there is 10GB + 5% free space before starting the log collection. #> [CmdletBinding()] [OutputType([void])] param ( # The name of the cluster to collect SDDC and Cluster Performance History [Parameter(Mandatory = $true, Position=0, HelpMessage="Enter the Cluster Name")] [ValidateScript({Get-Cluster -Name $_})] [string]$ClusterName, # The time frame for the performance history [Parameter(Mandatory = $false,Position=1)] [ValidateSet("LastHour","LastDay","LastWeek","LastMonth","LastYear")] # Default is LastDay [string]$PerformanceHistoryTimeFrame = "LastDay", # The root path to store the output files [Parameter(Mandatory = $false,Position=2)] [ValidateScript({ if ($_ -match '^\\\\') { throw "UNC paths are not supported. Use a local drive letter path (e.g., C:\Temp)." } if ($_ -notmatch '^[A-Za-z]:\\') { throw "Path must start with a drive letter (e.g., C:\Temp)." } Test-Path -Path ($_.Substring(0,3)) })] # Must be a local drive letter path, not a UNC path # Default is C:\Temp, if not specified [string]$OutputRootPath = "C:\Temp", # Optional switch, used to ignore disk space check for log collection [Parameter(Mandatory=$false,Position=3)] [Switch]$IgnoreDiskSpaceCheck, [Parameter(Mandatory = $false,Position=4)] [switch]$ExcludeClusterPerformanceHistory, # optional switch, to exclude cluster performance history from the diagnostic information [Parameter(Mandatory=$false, HelpMessage="Optional switch to prevent console output from the function.")] [switch]$NoOutput ) begin { # Requires administrator permissions to run this function if (-not (Test-Elevation)) { throw "This function must be run as an Administrator." } } process { # Handle -NoOutput: suppress all console output if ($NoOutput.IsPresent) { $script:SilentMode = $true $VerbosePreference = 'SilentlyContinue' $DebugPreference = 'SilentlyContinue' } # Check path and disk space [uint32]$LogCollectionFileSize = 10240 # 10GB, approx log collection size try { $Disk = Get-PSDrive -ErrorAction Stop | Where-Object { $PSItem.Root -eq $OutputRootPath.Substring(0,3) } } catch { Throw "Failed to query disk drives using Get-PSDrive: $($_.Exception.Message)" } Write-Output "Target disk free space = $([math]::round($Disk.Free / 1GB,2)) GiB" # Add the minimum / expected disk space required for log collection, plus 5% of the total disk space $MinimumRequiredDiskSpace = [math]::round($LogCollectionFileSize*1Mb/1Gb + ((($disk.Free + $disk.Used)/1Gb) * 0.05),2) if (($Disk.Free/1Gb -lt $MinimumRequiredDiskSpace) -and (-not($IgnoreDiskSpaceCheck.IsPresent))) { Write-Output "$($OutputRootPath.Substring(0,3)) disk free space is below minimum recommended size for log collection, plus 5% of total space as reserve" Throw "Insufficient disk space on the drive '$($OutputRootPath.Substring(0,3))' to store the output log files. Minimum recommended disk space is $MinimumRequiredDiskSpace GiB, increase space or consider use of '-IgnoreDiskSpaceCheck' switch." } else { if($IgnoreDiskSpaceCheck.IsPresent){ Write-Output "*** Free disk space checks have been ignored, proceeding with log collection ***" } else { Write-Output "Info: $($OutputRootPath.Substring(0,3)) has $([math]::round($Disk.Free/1Gb,2)) free disk space, this is above minimum recommended for log collection + reserve of 5% of total disk size ($MinimumRequiredDiskSpace GiB), performing log collection...." } } # Get the current date in the format yyyyMMdd, used for the output folders $DateFormatted = Get-Date -f "yyyyMMdd" if(-not(Test-Path -Path $OutputRootPath)){ Write-Output "Creating '$OutputRootPath\ output folder" try { New-Item -Path "$OutputRootPath" -ItemType Directory -Force | Out-Null } catch { Throw "Failed to create '$OutputRootPath' output folder $($_.Exception.Message)" } } # Create a folder to store the output files if(-not(Test-Path -Path "$OutputRootPath\Logs")){ Write-Output "Creating '$OutputRootPath\SDDC-Logs\$($DateFormatted)-ClusterPerf' temporary output folder" try { New-Item -Path "$OutputRootPath\SDDC-Logs\$($DateFormatted)-ClusterPerf" -ItemType Directory -Force | Out-Null } catch { Throw "Failed to create '$OutputRootPath\SDDC-Logs\$($DateFormatted)-ClusterPerf' output folder $($_.Exception.Message)" } Write-Output "Creating '$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf' target folder for the output zip file" try { New-Item -Path "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf" -ItemType Directory -Force | Out-Null } catch { Throw "Failed to create '$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf' output folder $($_.Exception.Message)" } } # Get the SDDC diagnostic information, including the cluster performance history Write-Output "Getting the SDDC diagnostic information for cluster '$ClusterName'..." if($ExcludeClusterPerformanceHistory.IsPresent){ # Exclude cluster performance history from the diagnostic information # Exclude cluster performance history from the diagnostic information Write-Output "Excluding cluster performance history from the diagnostic information" # Get the SDDC diagnostic information, including the cluster performance history try { Get-SddcDiagnosticInfo -WriteToPath "$OutputRootPath\SDDC-Logs\$($DateFormatted)-ClusterPerf" ` -ClusterName "$ClusterName" ` -IncludeGetNetView ` -ZipPrefix "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf" ` -IncludePerformance $true ` -DaysOfArchive 0 ` -ErrorAction Stop } catch { Throw "Failed to collect SDDC diagnostic information (excluding cluster performance history): $($_.Exception.Message)" } } else { # Include cluster performance history from the diagnostic information # Include cluster performance history from the diagnostic information try { Get-SddcDiagnosticInfo -WriteToPath "$OutputRootPath\SDDC-Logs\$($DateFormatted)-ClusterPerf" ` -ClusterName "$ClusterName" ` -IncludeGetNetView ` -ZipPrefix "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf" ` -IncludeClusterPerformanceHistory ` -PerformanceHistoryTimeFrame $PerformanceHistoryTimeFrame ` -IncludePerformance $true ` -DaysOfArchive 0 ` -ErrorAction Stop } catch { Throw "Failed to collect SDDC diagnostic information (including cluster performance history): $($_.Exception.Message)" } } # Confirm with user before deleting the output zip file: try { $ZipFile = Get-Item -Path "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf*.zip" } catch { Throw "Failed to get the SDDC Zip File $($_.Exception.Message)" } # Ensure only a single zip file is found: if($ZipFile.count -eq 1){ Write-Output "SDDC Zip file = '$($ZipFile.FullName)'" } else { Throw "Found more than 1 x zip file using this wildcard path: '$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf*.zip'" } # Extract the zip file to the target "SDDC" folder for sending the diagnostic information to Microsoft, as this folder is shown in the ingestion process Write-Output "Extracting the zip file '$($ZipFile.FullName)' to '$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf\SDDC' folder" New-Item -ItemType Directory -Path "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf\SDDC" -Force | Out-Null try { Expand-Archive -Path $ZipFile.FullName -DestinationPath "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf\SDDC" -Force } catch { Throw "Failed to extract the zip file $($_.Exception.Message)" } # Identify the GetNetView zip files in the target "SDDC" folder as these need to be extracted for the pipeline to ingest them $GetNetViewZipFiles = Get-ChildItem -Path "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf\SDDC" -Recurse -File -Include "*.zip" | Where-Object {$_.FullName -ilike '*GetNetView*' -and $_.Name -ilike 'msdbg.*'} foreach ($GetNetViewZipFile in $GetNetViewZipFiles) { Write-Output "Extracting the GetNetView zip file '$($GetNetViewZipFile.FullName)' to '$($GetNetViewZipFile.DirectoryName)' folder" try { New-Item -ItemType Directory -Path "$($GetNetViewZipFile.DirectoryName)\msdbg" -Force | Out-Null Expand-Archive -Path $GetNetViewZipFile.FullName -DestinationPath "$($GetNetViewZipFile.DirectoryName)\msdbg" -Force if (Test-Path -Path $GetNetViewZipFile.FullName) { Write-Output "Removing GetNetView zip file '$($GetNetViewZipFile.FullName)' in extracted files to reduce upload data" Remove-Item -Path $GetNetViewZipFile.FullName -Force } } catch { Throw "Failed to extract the GetNetView zip file $($_.Exception.Message)" } } # Send the diagnostic information to Microsoft, use "-CollectSddc $false" parameter, as SDDC event logs are collected as part of Get-SddcDiagnosticInfo try { Write-Output "Sending the diagnostic information to Microsoft..." Send-DiagnosticData -CollectSddc $false -SupplementaryLogs "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf\SDDC" -Verbose -ErrorAction Continue } catch { Throw "Failed to send the diagnostic information to Microsoft using Send-DiagnosticData $($_.Exception.Message)" } # Remove the SDDC folder, after sending the diagnostic information try { Remove-Item -Path "$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf\SDDC" -Recurse } catch { Throw "Failed to remove the '$OutputRootPath\SDDC\$($DateFormatted)-ClusterPerf\SDDC' folder $($_.Exception.Message)" } # Confirm with user before deleting the output zip file: if ($script:SilentMode) { $DeleteConfirmation = "N" } else { $DeleteConfirmation = Read-Host "Do you want to DELETE the zip file '$($ZipFile.Name)', - ($([math]::round($zipfile.Length/1MB,2)) MiB) ? (Y/N)" -ErrorAction Stop } if($DeleteConfirmation -ne "Y"){ Write-Output "Delete zip file cancelled by user." return } else { Write-Output "Deleting zip file '$($ZipFile.FullName)'" Remove-Item -Path $ZipFile.FullName -ErrorAction Stop -Verbose } } # End of process block end { if ($NoOutput.IsPresent) { $script:SilentMode = $false } Write-Debug "Completed Send-ClusterPerformanceHistory function" } } # End of Send-ClusterPerformanceHistory |