Reporting/ServerRake.Reporting.System.ps1
|
################################## ### COMMON FUNCTIONS: UPDATE ### ################################## function Export-SystemReport { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string[]] $ComputerName, [Parameter(Mandatory = $true)] [string[]] $MaintenanceWindows, [Parameter()] [string] $ExportPath ) $remoteScript = { param ($MaintenanceWindows) # ADMINISTRATORS $ADMINISTRATORS_Users = Get-LocalGroupMember -Name "Administrators" | ? ObjectClass -EQ "User" $ADMINISTRATORS_Groups = Get-LocalGroupMember -Name "Administrators" | ? ObjectClass -EQ "Group" # SERVICES $SERVICES_AllServices = Get-Service # VOLUMES $VOLUMES_AllVolumes = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" # NETWORKING $NETWORKING_Nic = Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where-Object IPEnabled $NETWORKING_OpenPorts = Get-NetTCPConnection -State Listen, Established | Sort-Object LocalPort -Unique # PATCHING $PATCHING_Hotfixes = Get-HotFix | Select-Object -Property Description, HotFixID, InstalledOn | Sort-Object -Property InstalledOn -Descending $PATCHING_TaniumGroup = Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Tanium\Tanium Client\Sensor Data\Tags' $PATCHING_TaniumGroup = ($PATCHING_TaniumGroup | Get-Member) | Where-Object { $_.Name -like "SRV*" -or $_.Name -like "WRK*" } | Select-Object -Property Name # $PATCHING_ManualPatch = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Tanium\Tanium Client\Sensor Data\Tags" # SYSTEM $SYSTEM_ComputerInfo = Get-ComputerInfo | Select-Object -Property WindowsProductName, WindowsEditionId, CsManufacturer, ` CsModel, CsDomain, CsDomainRole, TimeZone $SYSTEM_Ram = Get-CimInstance win32_ComputerSystem | % { [math]::round($_.TotalPhysicalMemory / 1GB) } $SYSTEM_CpuCores = (Get-CimInstance -ClassName Win32_Processor).NumberOfCores # LOGS $LOGS_SystemErrors = Get-WinEvent -FilterHashtable @{LogName='System'; Level=2,3} -MaxEvents 100 $LOGS_ApplicationErrors = Get-WinEvent -FilterHashtable @{LogName='Application'; Level=2,3} -MaxEvents 100 # PROGRAMS $PROGRAMS_Installed = @() $PROGRAMS_Installed += Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $PROGRAMS_Installed += Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" $PROGRAMS_Installed = $PROGRAMS_Installed | Where-Object { $null -ne $_.DisplayName } | Select-Object -Property DisplayName, DisplayVersion, Publisher, InstallDate | Sort-Object -Property Publisher # ENVIRONMENT & TIER switch -Regex ($env:COMPUTERNAME.SubString($env:COMPUTERNAME.length - 1) -match '^\d+$') { $true { $environmentInt = 3; $tierInt = 6; } $false { $environmentInt = 4; $tierInt = 6; } } switch -Wildcard ($env:COMPUTERNAME.Substring($env:COMPUTERNAME.length - $environmentInt)) { "p*" { if ($env:COMPUTERNAME.Substring(2, 3) -eq 'KAN') { $environment = "DR" } else { $environment = "PRODUCTION" }; } "r*" { $environment = "DR" } "s*" { $environment = "NON-PRODUCTION" } default { $environment = "?" } } switch -Wildcard ($env:COMPUTERNAME.Substring($env:COMPUTERNAME.Length - $tierInt)) { "ap*" { $tier = "APPLICATION" } "sr*" { $tier = "REPORTING" } "we*" { $tier = "WEB" } "sq*" { $tier = "DATABASE" } "ql*" { $tier = "DATABASE" } default { $tier = "?" } } # FORMATTING: MAX CELL CHARACTERS ALLOWED BY GOOGLE SHEETS --- 50,000 $GoogleCellCharThrottle = 49000 # FORMATTING: PSOBJECTS TO STRINGS (FOR SHEET CELLS) if ($SERVICES_AllServices) { $ServiceStatus = $SERVICES_AllServices | % { "$($_.Status) --- $($_.Name) ::: $($_.DisplayName)`n" } } else { $ServiceStatus = ' ' } if ($PATCHING_Hotfixes) { $PatchingStatus = $PATCHING_Hotfixes | % { "$($_.HotFixID) --- $($_.InstalledOn) --- $($_.Description)`n" } } else { $PatchingStatus = ' ' } if ($PATCHING_TaniumGroup.Name -in $MaintenanceWindows.Keys) { $PatchingWindow = $MaintenanceWindows[$PATCHING_TaniumGroup.Name] $PatchingWindow = "$($PATCHING_TaniumGroup.Name) --- $($PatchingWindow.Day) --- $($PatchingWindow.Start) (Start) --- $($PatchingWindow.End) (End)" } else { $PatchingWindow = "$($PATCHING_TaniumGroup.Name) --- no schedule information available." } if ($LOGS_SystemErrors) { $SystemErrors = $LOGS_SystemErrors | % { "$($_.TimeCreated) --- $($_.LevelDisplayName) --- $($_.ProviderName) ::::[$($_.Message)]`n`n" } # VALIDATION: GOOGLE CHARACTER LIMIT $count = -1 while ((-join $SystemErrors).Length -gt $GoogleCellCharThrottle) { $SystemErrors[$count] = $null $count-- } } else { $SystemErrors = ' ' } if ($LOGS_ApplicationErrors) { $ApplicationErrors = $LOGS_ApplicationErrors | % { "$($_.TimeCreated) --- $($_.LevelDisplayName) --- $($_.ProviderName) :::: [$($_.Message)]`n`n" } # VALIDATION: GOOGLE CHARACTER LIMIT $count = -1 while ((-join $SystemErrors).Length -gt $GoogleCellCharThrottle) { $ApplicationErrors[$count] = $null $count-- } } else { $ApplicationErrors = ' ' } if ($PROGRAMS_Installed) { $ProgramsInstalled = $PROGRAMS_Installed | % { "$($_.DisplayName)`n[Publisher] $($_.Publisher) --- [Install Date] $($_.InstallDate) --- v$($_.DisplayVersion)`n`n" } } else { $ProgramsInstalled = ' ' } if ($VOLUMES_AllVolumes) { $VolumeInformation = $VOLUMES_AllVolumes | % { "$($_.DeviceID) --- $($_.VolumeName) --- $([Math]::Round($_.Size/1GB, 2)) (Total) --- $([Math]::Round($_.FreeSpace/1GB, 2)) (Free)`n" } } else { $VolumeInformation = ' ' } if ($ADMINISTRATORS_Users) { $LocalAdmins = ($ADMINISTRATORS_Users.Name).split(' ') | % { "$($_)`n" } } else { $LocalAdmins = ' ' } if ($ADMINISTRATORS_Groups) { $AdminGroups = ($ADMINISTRATORS_Groups.Name).split(' ') | % { "$($_)`n" } } else { $AdminGroups = ' ' } if ($NETWORKING_OpenPorts) { $OpenPorts = '' $NETWORKING_OpenPorts | % { $process = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue $service = Get-CimInstance -ClassName Win32_Service -Filter "ProcessId = $($_.OwningProcess)" -ErrorAction SilentlyContinue $OpenPorts += "$($_.LocalPort) (Local) >>> $(if ($($_.RemotePort -ne 0)) {"$($_.RemotePort) (Remote) :"} else {"$($_.State) :"}) $(if ($($_.AppliedSetting)) {"$($_.AppliedSetting) :"}) $($process.ProcessName) $(if ($service) {"- $($service.DisplayName)"} else {"- $($process.Description)"})`n" } } else { $OpenPorts = ' ' } # RESPONSE OBJECT $response = [PSCustomObject]@{ 'Host Name' = $env:COMPUTERNAME 'Environment' = $environment 'Tier' = $tier 'Local Administrators' = $LocalAdmins 'Administrative Groups' = $AdminGroups 'OS' = $SYSTEM_ComputerInfo.WindowsProductName 'OS Version' = $SYSTEM_ComputerInfo.WindowsEditionId 'CPU Cores' = $SYSTEM_CpuCores 'RAM (GB)' = $SYSTEM_Ram 'Volumes (GB)' = $VolumeInformation 'Patching' = $PatchingStatus 'Patch Window (Local Time)' = $PatchingWindow 'Time Zone' = $SYSTEM_ComputerInfo.TimeZone 'Virtualization' = $SYSTEM_ComputerInfo.CsManufacturer 'Hypervisor' = $SYSTEM_ComputerInfo.CsModel 'Domain' = $SYSTEM_ComputerInfo.CsDomain 'Domain Role' = $SYSTEM_ComputerInfo.CsDomainRole 'IP Address' = $NETWORKING_Nic | % { "$($_.IPAddress)`n" } 'Default Gateway' = $NETWORKING_Nic | % { "$($_.DefaultIPGateway)`n" } 'Subnet' = $NETWORKING_Nic | % { "$($_.IPSubnet)`n" } 'MAC Address' = $NETWORKING_Nic.MacAddress 'Open Ports' = $OpenPorts 'Service Status' = $SERVICEStatus 'Programs Installed' = $ProgramsInstalled 'System Errors (100 Events)' = $SystemErrors 'Application Errors (100 Events)' = $ApplicationErrors } Write-Host "Data Collected [$env:COMPUTERNAME]" return $response } $response = Send-RemoteScript -ComputerName $ComputerName -RemoteScript $remoteScript -ArgumentList $MaintenanceWindows if ($ExportPath) { try { $csvArray = @() $response | % {$csvArray += $_ | Select-Object -Property * -ExcludeProperty PSComputerName, PSShowComputerName, RunspaceId} $csvArray | Export-Csv -Path "$ExportPath\System_Report_$(Get-Date -Format "yyyyMMdd_HHmmss").csv" -NoTypeInformation Write-Host "`nCSV file successfully exported to [$($ExportPath)].`n" -ForegroundColor Green } catch { throw $_ } } else { return $response } } function Export-StorageReport { [CmdletBinding()] param ( [Parameter(Mandatory = $True)] [String[]] $ComputerName, [Parameter(Mandatory = $True)] [String[]] $PrismCentral ) if (!$secret) { throw "No secret sessions are currently opened. Start a session with 'Open-SecretSession' and try again." } if (!$nxAPICreds) { throw "No Nutanix credentials have been set. Use 'Set-NutanixCredentials -Username' to set credentails and try again." } $response = @() $serversDisk = Get-SystemDrives -ComputerName $ComputerName $serversRam = Get-SystemRam -ComputerName $ComputerName foreach ($pc in $PrismCentral) { $baseUrl = "https://$($pc):9440/api/nutanix/v3" $Headers = @{ "Authorization" = "Basic $nxAPICreds" "Content-Type" = "application/json" "Accept" = "application/json" } # NUTANIX STORAGE CONTAINERS $containerMap = @{} $offsetby = 0 $count = 0 $totalContainersFound = $null do { $count += 500 $containerBody = @{ entity_type = "storage_container" group_member_count = $count group_member_offset = $offsetby group_member_attributes = @( @{ attribute = "container_name" } ) } | ConvertTo-Json -Depth 5 try { $containerResponse = Invoke-RestMethod -Uri "$baseUrl/groups" -Headers $Headers -Method Post -Body $containerBody -SkipCertificateCheck } catch { throw $_ } foreach ($sc in $containerResponse.group_results[0].entity_results) { $uuid = $sc.entity_id $name = ($sc.data | Where-Object { $_.name -eq "container_name" }).values[0].values[0] if ($uuid -and $name) { $containerMap[$uuid] = $name } } if (!$totalContainersFound) {$totalContainersFound = $containerResponse.metadata.total_matches} $offsetby += 500 } while ($count -lt $totalContainersFound) # VMs ---> RESPONSE $offsetby = 0 $count = 0 $totalVMsFound = $null do { $count += 500 $vmBody = @{ kind = "vm" offset = $offsetby length = $count } | ConvertTo-Json try { $vmResponse = Invoke-RestMethod -Uri "$baseUrl/vms/list" -Headers $headers -Method Post -Body $vmBody -SkipCertificateCheck } catch { throw $_ } foreach ($vm in $vmResponse.entities) { if (($vm.spec.name).ToUpper() -in $ComputerName) { #$serversDisk.Server $containers = [System.Collections.Generic.HashSet[string]]::new() $diskList = $vm.status.resources.disk_list if ($diskList) { foreach ($disk in $diskList) { $scUuid = $disk.device_properties.disk_address.storage_container_uuid $scRefName = $disk.storage_config.storage_container_reference.name if ($scRefName) { [void]$containers.Add($scRefName) } elseif ($scUuid -and $containerMap.ContainsKey($scUuid)) { [void]$containers.Add($containerMap[$scUuid]) } elseif ($scUuid) { [void]$containers.Add($scUuid) } } } $totalGB = ((($serversDisk | ? Server -eq $vm.spec.name).'Disk Size (GB)') | Measure-Object -Sum).Sum $freeGB = ((($serversDisk | ? Server -eq $vm.spec.name).'Disk Free (GB)') | Measure-Object -Sum).Sum $usedGB = $totalGB - $freeGB $usedPct = [Math]::Round(($usedGB / $totalGB) * 100, 2) $Ram = ($serversRam | ? Server -eq $vm.spec.name).'Memory (GB)' $response += [PSCustomObject]@{ Nutanix = $PrismCentral Server = ($vm.spec.name).ToUpper() 'VM Power State' = $vm.spec.resources.power_state 'VM Storage Capacity (GiB)' = $totalGB 'VM Storage Used (GiB)' = $usedGB 'VM Storage Free (GiB)' = $freeGB 'VM Storage Used %' = $usedPct 'VM Memory' = $Ram 'VM Storage Datastore(s)' = if ($containers.Count -gt 0) { ($containers -join ", ") } else { "N/A" } } Write-Host "Data collected [$(($vm.spec.name).ToUpper())]" } } if (!$totalVMsFound) {$totalVMsFound = $vmResponse.metadata.total_matches} $offsetby += 500 } while ($count -lt $totalVMsFound) } return $response } function Export-ADCOReport { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [String] $Jumphost, [Parameter(Mandatory = $true)] [String[]] $ComputerName ) $COs = Get-ADCOs -Jumphost $Jumphost -ComputerName $ComputerName $AdminUsers = Get-AdminUsers -ComputerName $ComputerName $AdminGroups = Get-AdminGroups -ComputerName $ComputerName $response = @() foreach ($co in $COs) { $admins = $AdminUsers | ? Server -eq $co.Name | select -Property 'Admin Name' | % {$_.'Admin Name'} $groups = $AdminGroups | ? Server -eq $co.Name | select -Property 'Group Name' | % {$_.'Group Name'} $memberships = $co.MemberOf | % { ($_ -split ',')[0].Substring(3) } $response += [PSCustomObject]@{ Server = $co.Name "AD DNS Name" = $co.DNS "AD IP Address" = $co.IPv4Address "AD CO Created" = $co.whenCreated "AD CO Location" = $co.CanonicalName "AD Lockout State" = $co.LockedOut "AD Password Changed" = $co.PasswordLastSet "AD Primary Group" = ($co.PrimaryGroup -split ',')[0].Substring(3) "AD Memberships" = $memberships "Guest OS Admins" = $admins -join "`n" "Guest OS Groups" = $groups -join "`n" } } return $response } |