Initial commit

This commit is contained in:
Tyler Hale 2021-09-14 14:12:03 -06:00
parent a6c6d51fc3
commit d4b9ed2d89
Signed by: Tyler
GPG key ID: 3F9270F8F70AC13D
4 changed files with 521 additions and 5 deletions

416
Get-SystemStatus.ps1 Normal file
View file

@ -0,0 +1,416 @@
<#
.SYNOPSIS
Gets various information related to a running system's status for reporting.
.DESCRIPTION
Gathers the follow information from a provided list of computers.
The collected data is then returned as a DataTable or can be exported to a variety of file formats.
Optional Metadata can be included to be included in the returned results/reports to assist in machine identification.
Collected Data: Computer Name, Operating System, Operating System Build, Uptime, Recent Updates, Disk Space Utilization, Date Gathered
Optional Metadata: Organization, Role, UpdateWindow
.PARAMETER ComputerName
Specifies a computer or set of computers that should be queried for their status.
.PARAMETER CsvPath
Path to a CSV that contains the list computers that should be collected.
Optional metadata can be included that will be included in returned data.
Columns:
Name*
Organization
Role
UpdateWindow
*: Required
.PARAMETER Credential
Credentials used for connecting to the specified computers to gather the machine's status information.
.PARAMETER CredentialPath
Path to stored credentials that will be imported using Import-Clixml to allow for storing credentials using a secure method.
.PARAMETER OutputType
Style of report that should be output. Defaults to JSON output but can be exported as a CSV or JSON.
.PARAMETER OutputPath
Path to where the report should be saved.
.PARAMETER Organization
Optional metadata that can be included in the returned results.
.PARAMETER Role
Optional metadata that can be included in the returned results.
.PARAMETER UpdateWindow
Optional metadata that can be included in the returned results.
.NOTES
Version: 1.0
Author: Tyler Hale
Creation Date: 2021.09.14
#>
[CmdletBinding(DefaultParameterSetName = 'Local')]
param (
[Parameter(Mandatory = $true, ParameterSetName = "CnDefaultCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CnDefaultCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CnCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CnCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CnStoredCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CnStoredCredReport")]
[ValidateScript( { Test-Connection $_ -Count 2 } )]
[alias('Cn')]
[string[]]
$ComputerName,
[Parameter(Mandatory = $true, ParameterSetName = "CsvDefaultCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvDefaultCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvStoredCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvStoredCredReport")]
[ValidateNotNullOrEmpty()]
[ValidateScript( { Test-Path -Path $_ } )]
[string]
$CsvPath,
[Parameter(Mandatory = $true, ParameterSetName = "CnCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CnCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvCredReport")]
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty,
[Parameter(Mandatory = $true, ParameterSetName = "CnStoredCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CnStoredCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvStoredCred")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvStoredCredReport")]
[ValidateNotNullOrEmpty()]
[ValidateScript( { Test-Path -Path $_ })]
[string]
$CredentialPath,
[Parameter(Mandatory = $false, ParameterSetName = "LocalReport")]
[Parameter(Mandatory = $false, ParameterSetName = "CnDefaultCredReport")]
[Parameter(Mandatory = $false, ParameterSetName = "CnCredReport")]
[Parameter(Mandatory = $false, ParameterSetName = "CnStoredCredReport")]
[Parameter(Mandatory = $false, ParameterSetName = "CsvDefaultCredReport")]
[Parameter(Mandatory = $false, ParameterSetName = "CsvCredReport")]
[Parameter(Mandatory = $false, ParameterSetName = "CsvStoredCredReport")]
[ValidateSet("CSV", "JSON", "HTML")]
[string]
$OutputType = "JSON",
[Parameter(Mandatory = $true, ParameterSetName = "LocalReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CnDefaultCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CnCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CnStoredCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvDefaultCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvCredReport")]
[Parameter(Mandatory = $true, ParameterSetName = "CsvStoredCredReport")]
[string]
$OutputPath,
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]
$Organization,
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]
$Role,
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]
$UpdateWindow
)
############################################### [Script Settings] ################################################
# Define Default Columns
[System.Collections.ArrayList]$Columns = @(
"Computer Name",
"Operating System",
"Operating System Build",
"Uptime",
"Recent Updates",
"Disk Space Utilization",
"Date Gathered"
)
# Define optional columns that will be removed if not provided
[System.Collections.ArrayList]$OptionalColumns = @(
"Role"
"Organization"
"UpdateWindow"
)
# HTML Header for table formatting
$Head = @"
<style>
body {
font-family: "Arial";
font-size: 8pt;
color: #4C607B;
}
th, td {
border: 1px solid #e57300;
border-collapse: collapse;
padding: 5px;
}
th {
font-size: 1.2em;
text-align: left;
background-color: #003366;
color: #ffffff;
white-space:nowrap;
}
td {
color: #000000;
white-space: pre;
}
.even { background-color: #ffffff; }
.odd { background-color: #bfbfbf; }
</style>
"@
################################################## [Functions] ###################################################
function Format-DataSizes ($Size) {
switch ($Size) {
{ $_ -ge 1PB } { "{0:#.#'P'}" -f ($Size / 1PB); break }
{ $_ -ge 1TB } { "{0:#.#'T'}" -f ($Size / 1TB); break }
{ $_ -ge 1GB } { "{0:#.#'G'}" -f ($Size / 1GB); break }
{ $_ -ge 1MB } { "{0:#.#'M'}" -f ($Size / 1MB); break }
{ $_ -ge 1KB } { "{0:#'K'}" -f ($Size / 1KB); break }
default { "{0}" -f ($Size) + "B" }
}
}
function Format-TimeSpan {
process {
"{0:00} Day(s) {1:00}:{2:00}:{3:00}" -f $_.Days, $_.Hours, $_.Minutes, $_.Seconds
}
}
function Add-RowEntry {
[CmdletBinding()]
param (
$Table,
$Name = $OperatingSystem.CSName,
$Role,
$Organization = $OperatingSystem.Organization,
$OperatingSystem,
$LogicalDisk,
$Updates,
$UpdateWindow,
$DateGathered,
$OptionalColumns
)
# Create a row
$Row = $Table.NewRow()
# Define the computer name
$Row."Computer Name" = $Name
$Row."Date Gathered" = $DateGathered
# OS
if ($null -ne ($OperatingSystem)) {
$Row."Operating System" = "$($OperatingSystem.Caption)"
$Row."Operating System Build" = "$($OperatingSystem.Version)"
$Row."Uptime" = "$((New-TimeSpan -Start ($OperatingSystem.LastBootUpTime) -End $DataGatheredDate) | Format-TimeSpan)"
}
# Disk
if ($null -ne ($LogicalDisk)) {
[string]$DiskUsage = ""
$LogicalDisk | ForEach-Object {
if ($null -ne $_.Size) {
$FreeSpace = Format-DataSizes -Size $_.FreeSpace
$TotalSize = Format-DataSizes -Size $_.Size
$DiskUsage += "$($_.DeviceID) $($TotalSize) Total \ $($FreeSpace) Free - {0:P0}`n" -f ($_.FreeSpace / $_.Size)
}
}
$Row."Disk Space Utilization" = $DiskUsage.TrimEnd()
}
# Updates
if ($null -ne ($Updates)) {
$Row."Recent Updates" = ""
$RecentUpdates = ($Updates | Sort-Object InstalledOn -Descending) | Select-Object -First 3
foreach ($Update in $RecentUpdates) {
$Row."Recent Updates" += "$(($Update.InstalledOn | Select-String -Pattern "(.*)(?= 00:00:00)").Matches.Value) - $($Update.HotFixID)`n"
}
}
# Optional Columns
foreach ($OptionalColumn in $OptionalColumns) {
if ($Table.Columns -match "$OptionalColumn") {
$Row."$OptionalColumn" = (Get-Variable -Name "$OptionalColumn").Value
}
}
# Add the row to the table
$Table.Rows.Add($Row)
}
############################################# [Internal Processing] ##############################################
# Change to the script's current directory to include support for relative paths
Set-Location $PSScriptRoot
# Determine execution scope based on parameter set
Write-Verbose "ParameterSetName: $($PSCmdlet.ParameterSetName)"
switch -Wildcard ($PSCmdlet.ParameterSetName) {
"Local*" {
$Computers = [PSCustomObject]@{
Name = $env:COMPUTERNAME
Role = $Role
Organization = $Organization
UpdateWindow = $UpdateWindow
}
}
"Cn*" {
# If the only computer name provided is the current machine,
# Switch back to using the Local parameter set and drop the
# ComputerName variable to avoid needing additional permissions
if ($ComputerName -ne $env:COMPUTERNAME) {
$Computers = foreach ($Computer in $ComputerName) {
[PSCustomObject]@{
Name = $Computer
Role = $Role
Organization = $Organization
UpdateWindow = $UpdateWindow
}
}
}
else {
$Computers = [PSCustomObject]@{
Name = $env:COMPUTERNAME
Role = $Role
Organization = $Organization
UpdateWindow = $UpdateWindow
}
Remove-Variable ComputerName
}
}
"Csv*" {
$Computers = Import-Csv -Path $CsvPath
[string[]]$ComputerName = $Computers.Name
}
}
# Add Optional Columns if they exist
foreach ($OptionalColumn in $OptionalColumns) {
switch ($OptionalColumn) {
"Organization" { [int]$ColumnPosition = 1 }
"Role" { [int]$ColumnPosition = 1 }
Default { [int]$ColumnPosition = $Columns.Count }
}
if ($null -ne $Computers."$($OptionalColumn)") {
if ('' -ne ($Computers."$($OptionalColumn)" | Out-String).Trim()) {
$Columns.Insert($ColumnPosition, "$OptionalColumn")
}
}
}
# If using stored credentials, import the credentials for future use
if ($PSCmdlet.ParameterSetName -like "*StoredCred*") {
$Credential = Import-Clixml -Path $CredentialPath
}
# Build Remote Parameters splat variable
$RemoteParameters = @{}
if ($null -ne $ComputerName) {
Write-Verbose "Adding $ComputerName to Remote Parameters splat variable"
$RemoteParameters['ComputerName'] = $ComputerName
$RemoteParameters['Authentication'] = "Kerberos"
}
if ($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
Write-Verbose "Adding provided credentials to Remote Parameters splat variable"
$RemoteParameters['Credential'] = $Credential
$RemoteParameters['Authentication'] = "Kerberos"
}
# Create Table object
$Table = New-Object system.Data.DataTable "Report"
foreach ($Column in $Columns) {
$Table.Columns.Add((New-Object system.Data.DataColumn $Column, ([string])))
$Table.Columns[$Column].DefaultValue = "Unknown"
}
################################################## [Execution] ###################################################
# Gather Cim Data
Write-Verbose "Started Data gathering: $(Get-Date -Format o)"
$CimMasterSession = New-CimSession @RemoteParameters
$CimMasterData = @{}
$CimMasterData["OS"] = Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $CimMasterSession
$CimMasterData["Drives"] = Get-CimInstance -ClassName "Win32_LogicalDisk" -Namespace "root\CIMV2" -CimSession $CimMasterSession
$CimMasterData["Updates"] = Get-CimInstance -ClassName "Win32_QuickfixEngineering" -CimSession $CimMasterSession
$DataGatheredDate = Get-Date -Format o
Write-Verbose "Finished Data gathering: $DataGatheredDate"
Remove-CimSession -CimSession $CimMasterSession
foreach ($Computer in ($Computers | Sort-Object Name)) {
Write-Verbose "Processing $($Computer.Name) - $(Get-Date -Format o)"
# Add Optional Parameters to the row as needed
$OptionalParameters = @{"OptionalColumns" = $OptionalColumns }
foreach ($OptionalColumn in $OptionalColumns) {
if ($null, '' -ne $Computer."$($OptionalColumn)") {
$OptionalParameters["$($OptionalColumn)"] = $Computer."$($OptionalColumn)"
}
}
# Created the row based on the provided data
# Local execution sets the PSComputerName as null
if ($null -ne $ComputerName) {
Add-RowEntry -Table $Table `
-Name $Computer.Name `
-OperatingSystem ($CimMasterData.OS | Where-Object { $_.PSComputerName -eq "$($Computer.Name)" }) `
-LogicalDisk ($CimMasterData.Drives | Where-Object { $_.PSComputerName -eq "$($Computer.Name)" }) `
-Updates ($CimMasterData.Updates | Where-Object { $_.PSComputerName -eq "$($Computer.Name)" }) `
-DateGathered $DataGatheredDate `
@OptionalParameters
}
else {
Add-RowEntry -Table $Table `
-Name $Computer.Name `
-OperatingSystem ($CimMasterData.OS | Where-Object { $null -eq $_.PSComputerName }) `
-LogicalDisk ($CimMasterData.Drives | Where-Object { $null -eq $_.PSComputerName }) `
-Updates ($CimMasterData.Updates | Where-Object { $null -eq $_.PSComputerName }) `
-DateGathered $DataGatheredDate `
@OptionalParameters
}
}
if ($PSCmdlet.ParameterSetName -like "*Report*") {
switch ($OutputType) {
"CSV" { $Table | Export-Csv -Path $OutputPath -NoTypeInformation }
"JSON" { $Table | Select-Object * -ExcludeProperty ItemArray, Table, RowError, RowState, HasErrors | ConvertTo-Json | Out-File -FilePath $OutputPath }
"HTML" { $Table | Select-Object -Property $Columns | ConvertTo-HTML -Head $Head -Body "<font color=`"Black`"><h2>System Status Update</h2><h3>Date Gathered: $DataGatheredDate</h3></font>" | Set-Content $OutputPath }
}
}
else {
$Table
}

BIN
Images/Example-Default.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
Images/Example-HTML.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

110
README.md
View file

@ -1,14 +1,110 @@
# Get-SystemStatus
Gets various information related to a running system's status for reporting.
Gathers the follow information from a provided list of computers.
The collected data is then returned as a DataTable or can be exported to a variety of file formats.
Optional Metadata can be included to be included in the returned results/reports to assist in machine identification.
## Requirements
Collected Data: Computer Name, Operating System, Operating System Build, Uptime, Recent Updates, Disk Space Utilization, Date Gathered
Optional Metadata: Organization, Role, UpdateWindow
## Variables
| Variable | Required | Default | Choices | Description |
| -------- | -------- | ------- | ------- | ----------- |
| | | | | |
### ComputerName Set
| Variable | Required | Default | Choices | Description |
| -------------- | -------- | ------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- |
| ComputerName | Yes | | | Specifies a computer or set of computers that should be queried for their status |
### CsvPath Set
| Variable | Required | Default | Choices | Description |
| -------------- | -------- | ------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- |
| CsvPath | Yes | | | Specifies a computer or set of computers that should be queried for their status |
### Credential Set
| Variable | Required | Default | Choices | Description |
| ---------- | -------- | ------- | ------- | ----------------------------------------------------------------------------------------------------- |
| Credential | Yes | | | Credentials used for connecting to the specified computers to gather the machine's status information |
### CredentialPath Set
| Variable | Required | Default | Choices | Description |
| -------------- | -------- | ------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| CredentialPath | Yes | | | Path to stored credentials that will be imported using Import-Clixml to allow for storing credentials using a secure method |
### Report Set
| Variable | Required | Default | Choices | Description |
| -------------- | -------- | ------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- |
| OutputType | No | JSON | CSV, JSON, HTML | Style of report that should be output |
| OutputPath | Yes | | | Path to where the report should be saved |
### Common Variables
| Variable | Required | Default | Choices | Description |
| -------------- | -------- | ------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Organization | No | | | Optional metadata that can be included in the returned results |
| Role | No | | | Optional metadata that can be included in the returned results |
| UpdateWindow | No | | | Optional metadata that can be included in the returned results |
## Syntax
```powershell
Get-SystemStatus.ps1 [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -ComputerName <String[]> -CredentialPath <String> [-OutputType <String>] -OutputPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -ComputerName <String[]> -CredentialPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -ComputerName <String[]> -Credential <PSCredential> [-OutputType <String>] -OutputPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -ComputerName <String[]> -Credential <PSCredential> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -ComputerName <String[]> [-OutputType <String>] -OutputPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -ComputerName <String[]> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -CsvPath <String> -CredentialPath <String> [-OutputType <String>] -OutputPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -CsvPath <String> -CredentialPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -CsvPath <String> -Credential <PSCredential> [-OutputType <String>] -OutputPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -CsvPath <String> -Credential <PSCredential> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -CsvPath <String> [-OutputType <String>] -OutputPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 -CsvPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
```powershell
Get-SystemStatus.ps1 [-OutputType <String>] -OutputPath <String> [-Organization <String>] [-Role <String>] [-UpdateWindow <String>] [<CommonParameters>]
```
## Example
@ -17,3 +113,7 @@ Gets various information related to a running system's status for reporting.
See LICENSE file for full license information.
## Screenshots
![Example Default Execution](Images/Example-Default.png?raw=true)
![Example Default Execution](Images/Example-HTML.png?raw=true)