Upload files to "/"
This commit is contained in:
@@ -0,0 +1,311 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[string]$OutputPath
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($OutputPath)) {
|
||||||
|
$desktop = [Environment]::GetFolderPath('Desktop')
|
||||||
|
if ([string]::IsNullOrWhiteSpace($desktop)) {
|
||||||
|
$desktop = $PSScriptRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
$OutputPath = Join-Path $desktop ("SystemInformation_{0}.txt" -f (Get-Date -Format 'yyyyMMdd_HHmmss'))
|
||||||
|
}
|
||||||
|
|
||||||
|
$report = New-Object System.Collections.Generic.List[string]
|
||||||
|
$steps = @(
|
||||||
|
'General system information'
|
||||||
|
'Windows version and uptime'
|
||||||
|
'CPU information'
|
||||||
|
'Memory information'
|
||||||
|
'GPU information'
|
||||||
|
'Network adapters and IP addresses'
|
||||||
|
'Windows product key'
|
||||||
|
'Windows update history'
|
||||||
|
'Writing report'
|
||||||
|
'Opening report in Notepad'
|
||||||
|
)
|
||||||
|
$stepNumber = 0
|
||||||
|
|
||||||
|
function Add-Line {
|
||||||
|
param([AllowEmptyString()][string]$Text = '')
|
||||||
|
$script:report.Add($Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Add-Section {
|
||||||
|
param([Parameter(Mandatory = $true)][string]$Title)
|
||||||
|
|
||||||
|
Add-Line
|
||||||
|
Add-Line ('=' * 78)
|
||||||
|
Add-Line $Title.ToUpperInvariant()
|
||||||
|
Add-Line ('=' * 78)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start-Step {
|
||||||
|
param([Parameter(Mandatory = $true)][string]$Name)
|
||||||
|
|
||||||
|
$script:stepNumber++
|
||||||
|
$percent = [int](($script:stepNumber / $script:steps.Count) * 100)
|
||||||
|
Write-Host ("[{0}/{1}] {2}..." -f $script:stepNumber, $script:steps.Count, $Name) -ForegroundColor Cyan
|
||||||
|
Write-Progress -Activity 'Collecting system information' -Status $Name -PercentComplete $percent
|
||||||
|
}
|
||||||
|
|
||||||
|
function Add-PropertyLines {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]$InputObject,
|
||||||
|
[Parameter(Mandatory = $true)][string[]]$Properties
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($property in $Properties) {
|
||||||
|
$value = $InputObject.$property
|
||||||
|
if ($null -eq $value -or "$value" -eq '') {
|
||||||
|
$value = 'Not available'
|
||||||
|
}
|
||||||
|
Add-Line ("{0,-28}: {1}" -f $property, $value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-ReportStep {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)][string]$Name,
|
||||||
|
[Parameter(Mandatory = $true)][scriptblock]$Action
|
||||||
|
)
|
||||||
|
|
||||||
|
Start-Step $Name
|
||||||
|
try {
|
||||||
|
& $Action
|
||||||
|
Write-Host ' Completed.' -ForegroundColor Green
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Add-Line ("Unable to collect this section: {0}" -f $_.Exception.Message)
|
||||||
|
Write-Warning (" {0}" -f $_.Exception.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ConvertFrom-DigitalProductId {
|
||||||
|
param([byte[]]$DigitalProductId)
|
||||||
|
|
||||||
|
if ($null -eq $DigitalProductId -or $DigitalProductId.Length -lt 67) {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
$keyCharacters = 'BCDFGHJKMPQRTVWXY2346789'
|
||||||
|
$keyOffset = 52
|
||||||
|
$isWindows8OrLater = [int](($DigitalProductId[66] / 6) -band 1)
|
||||||
|
$DigitalProductId[66] = [byte](($DigitalProductId[66] -band 0xF7) -bor (($isWindows8OrLater -band 2) * 4))
|
||||||
|
$decoded = ''
|
||||||
|
$last = 0
|
||||||
|
|
||||||
|
for ($i = 24; $i -ge 0; $i--) {
|
||||||
|
$current = 0
|
||||||
|
for ($j = 14; $j -ge 0; $j--) {
|
||||||
|
$current = ($current * 256) -bxor $DigitalProductId[$j + $keyOffset]
|
||||||
|
$DigitalProductId[$j + $keyOffset] = [byte][math]::Floor($current / 24)
|
||||||
|
$current = $current % 24
|
||||||
|
}
|
||||||
|
$decoded = $keyCharacters[$current] + $decoded
|
||||||
|
$last = $current
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isWindows8OrLater -eq 1) {
|
||||||
|
$decoded = $decoded.Insert($last, 'N')
|
||||||
|
if ($decoded.Length -gt 25) {
|
||||||
|
$decoded = $decoded.Substring(0, 25)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 5; $i -lt $decoded.Length; $i += 6) {
|
||||||
|
$decoded = $decoded.Insert($i, '-')
|
||||||
|
}
|
||||||
|
|
||||||
|
return $decoded
|
||||||
|
}
|
||||||
|
|
||||||
|
Add-Line 'SYSTEM INFORMATION REPORT'
|
||||||
|
Add-Line ("Generated : {0}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss K'))
|
||||||
|
|
||||||
|
Invoke-ReportStep 'General system information' {
|
||||||
|
Add-Section 'General System Information'
|
||||||
|
$computer = Get-CimInstance Win32_ComputerSystem
|
||||||
|
$bios = Get-CimInstance Win32_BIOS
|
||||||
|
|
||||||
|
Add-Line ("Hostname : {0}" -f $env:COMPUTERNAME)
|
||||||
|
Add-Line ("Logged-in user : {0}" -f $(if ($computer.UserName) { $computer.UserName } else { "$env:USERDOMAIN\$env:USERNAME" }))
|
||||||
|
Add-Line ("User domain : {0}" -f $env:USERDOMAIN)
|
||||||
|
Add-Line ("Computer domain/workgroup : {0}" -f $computer.Domain)
|
||||||
|
Add-Line ("Domain joined : {0}" -f $computer.PartOfDomain)
|
||||||
|
Add-Line ("Manufacturer : {0}" -f $computer.Manufacturer)
|
||||||
|
Add-Line ("Model : {0}" -f $computer.Model)
|
||||||
|
Add-Line ("System type : {0}" -f $computer.SystemType)
|
||||||
|
Add-Line ("Serial number : {0}" -f $bios.SerialNumber)
|
||||||
|
Add-Line ("BIOS version : {0}" -f ($bios.SMBIOSBIOSVersion -join ', '))
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-ReportStep 'Windows version and uptime' {
|
||||||
|
Add-Section 'Windows Version and Uptime'
|
||||||
|
$os = Get-CimInstance Win32_OperatingSystem
|
||||||
|
$windowsKey = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'
|
||||||
|
$now = Get-Date
|
||||||
|
$lastBoot = $os.LastBootUpTime
|
||||||
|
$uptime = $now - $lastBoot
|
||||||
|
|
||||||
|
Add-Line ("Windows product name : {0}" -f $windowsKey.ProductName)
|
||||||
|
Add-Line ("Edition ID : {0}" -f $windowsKey.EditionID)
|
||||||
|
Add-Line ("Display version : {0}" -f $windowsKey.DisplayVersion)
|
||||||
|
Add-Line ("Version : {0}" -f $os.Version)
|
||||||
|
Add-Line ("Build number : {0}" -f $os.BuildNumber)
|
||||||
|
Add-Line ("Update build revision (UBR) : {0}" -f $windowsKey.UBR)
|
||||||
|
Add-Line ("Full build : {0}.{1}" -f $os.BuildNumber, $windowsKey.UBR)
|
||||||
|
Add-Line ("Architecture : {0}" -f $os.OSArchitecture)
|
||||||
|
Add-Line ("Install date : {0}" -f $os.InstallDate)
|
||||||
|
Add-Line ("Last boot : {0}" -f $lastBoot)
|
||||||
|
Add-Line ("Uptime : {0} days, {1} hours, {2} minutes, {3} seconds" -f
|
||||||
|
[math]::Floor($uptime.TotalDays), $uptime.Hours, $uptime.Minutes, $uptime.Seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-ReportStep 'CPU information' {
|
||||||
|
Add-Section 'CPU Information'
|
||||||
|
$processors = Get-CimInstance Win32_Processor
|
||||||
|
$index = 0
|
||||||
|
|
||||||
|
foreach ($processor in $processors) {
|
||||||
|
$index++
|
||||||
|
Add-Line ("Processor {0}" -f $index)
|
||||||
|
Add-Line (" Name : {0}" -f $processor.Name.Trim())
|
||||||
|
Add-Line (" Manufacturer : {0}" -f $processor.Manufacturer)
|
||||||
|
Add-Line (" Physical cores : {0}" -f $processor.NumberOfCores)
|
||||||
|
Add-Line (" Logical processors : {0}" -f $processor.NumberOfLogicalProcessors)
|
||||||
|
Add-Line (" Current clock speed : {0} MHz" -f $processor.CurrentClockSpeed)
|
||||||
|
Add-Line (" Maximum clock speed : {0} MHz" -f $processor.MaxClockSpeed)
|
||||||
|
Add-Line (" Socket : {0}" -f $processor.SocketDesignation)
|
||||||
|
Add-Line (" Processor ID : {0}" -f $processor.ProcessorId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-ReportStep 'Memory information' {
|
||||||
|
Add-Section 'Memory Information'
|
||||||
|
$computer = Get-CimInstance Win32_ComputerSystem
|
||||||
|
$os = Get-CimInstance Win32_OperatingSystem
|
||||||
|
$modules = Get-CimInstance Win32_PhysicalMemory
|
||||||
|
$totalGB = [math]::Round($computer.TotalPhysicalMemory / 1GB, 2)
|
||||||
|
$freeGB = [math]::Round($os.FreePhysicalMemory * 1KB / 1GB, 2)
|
||||||
|
|
||||||
|
Add-Line ("Installed RAM : {0} GB" -f $totalGB)
|
||||||
|
Add-Line ("Available RAM : {0} GB" -f $freeGB)
|
||||||
|
Add-Line ("Used RAM : {0} GB" -f ([math]::Round($totalGB - $freeGB, 2)))
|
||||||
|
Add-Line
|
||||||
|
Add-Line 'Physical memory modules:'
|
||||||
|
|
||||||
|
$slot = 0
|
||||||
|
foreach ($module in $modules) {
|
||||||
|
$slot++
|
||||||
|
Add-Line (" Module {0}" -f $slot)
|
||||||
|
Add-Line (" Bank/slot : {0} / {1}" -f $module.BankLabel, $module.DeviceLocator)
|
||||||
|
Add-Line (" Capacity : {0} GB" -f ([math]::Round($module.Capacity / 1GB, 2)))
|
||||||
|
Add-Line (" Speed : {0} MT/s" -f $module.ConfiguredClockSpeed)
|
||||||
|
Add-Line (" Manufacturer : {0}" -f $module.Manufacturer)
|
||||||
|
Add-Line (" Part number : {0}" -f $module.PartNumber.Trim())
|
||||||
|
Add-Line (" Serial number : {0}" -f $module.SerialNumber)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-ReportStep 'GPU information' {
|
||||||
|
Add-Section 'GPU Information'
|
||||||
|
$gpus = Get-CimInstance Win32_VideoController
|
||||||
|
$index = 0
|
||||||
|
|
||||||
|
foreach ($gpu in $gpus) {
|
||||||
|
$index++
|
||||||
|
Add-Line ("GPU {0}" -f $index)
|
||||||
|
Add-Line (" Name : {0}" -f $gpu.Name)
|
||||||
|
Add-Line (" Adapter RAM : {0} GB" -f $(if ($gpu.AdapterRAM) { [math]::Round($gpu.AdapterRAM / 1GB, 2) } else { 'Not available' }))
|
||||||
|
Add-Line (" Driver version : {0}" -f $gpu.DriverVersion)
|
||||||
|
Add-Line (" Driver date : {0}" -f $gpu.DriverDate)
|
||||||
|
Add-Line (" Video processor : {0}" -f $gpu.VideoProcessor)
|
||||||
|
Add-Line (" Current resolution : {0} x {1} @ {2} Hz" -f $gpu.CurrentHorizontalResolution, $gpu.CurrentVerticalResolution, $gpu.CurrentRefreshRate)
|
||||||
|
Add-Line (" Status : {0}" -f $gpu.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-ReportStep 'Network adapters and IP addresses' {
|
||||||
|
Add-Section 'Network Adapters and IP Addresses'
|
||||||
|
$adapters = Get-CimInstance Win32_NetworkAdapterConfiguration |
|
||||||
|
Where-Object { $_.IPEnabled -or $_.MACAddress } |
|
||||||
|
Sort-Object -Property IPEnabled -Descending
|
||||||
|
|
||||||
|
$index = 0
|
||||||
|
foreach ($adapter in $adapters) {
|
||||||
|
$index++
|
||||||
|
Add-Line ("Adapter {0}" -f $index)
|
||||||
|
Add-Line (" Description : {0}" -f $adapter.Description)
|
||||||
|
Add-Line (" Enabled : {0}" -f $adapter.IPEnabled)
|
||||||
|
Add-Line (" MAC address : {0}" -f $adapter.MACAddress)
|
||||||
|
Add-Line (" DHCP enabled : {0}" -f $adapter.DHCPEnabled)
|
||||||
|
Add-Line (" DHCP server : {0}" -f $adapter.DHCPServer)
|
||||||
|
Add-Line (" IP addresses : {0}" -f $(if ($adapter.IPAddress) { $adapter.IPAddress -join ', ' } else { 'None' }))
|
||||||
|
Add-Line (" Subnets : {0}" -f $(if ($adapter.IPSubnet) { $adapter.IPSubnet -join ', ' } else { 'None' }))
|
||||||
|
Add-Line (" Default gateways : {0}" -f $(if ($adapter.DefaultIPGateway) { $adapter.DefaultIPGateway -join ', ' } else { 'None' }))
|
||||||
|
Add-Line (" DNS servers : {0}" -f $(if ($adapter.DNSServerSearchOrder) { $adapter.DNSServerSearchOrder -join ', ' } else { 'None' }))
|
||||||
|
Add-Line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-ReportStep 'Windows product key' {
|
||||||
|
Add-Section 'Windows Product Key'
|
||||||
|
$licensing = Get-CimInstance SoftwareLicensingService
|
||||||
|
$firmwareKey = $licensing.OA3xOriginalProductKey
|
||||||
|
$registry = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'
|
||||||
|
$decodedKey = ConvertFrom-DigitalProductId -DigitalProductId ([byte[]]$registry.DigitalProductId.Clone())
|
||||||
|
|
||||||
|
Add-Line ("Firmware/OEM key : {0}" -f $(if ($firmwareKey) { $firmwareKey } else { 'Not embedded or not available' }))
|
||||||
|
Add-Line ("Registry-decoded key : {0}" -f $(if ($decodedKey) { $decodedKey } else { 'Not available' }))
|
||||||
|
Add-Line 'Note: Digital licenses and volume licensing may not expose the currently active key.'
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-ReportStep 'Windows update history' {
|
||||||
|
Add-Section 'Windows Update History'
|
||||||
|
$hotFixes = Get-HotFix |
|
||||||
|
Where-Object { $null -ne $_.InstalledOn } |
|
||||||
|
Sort-Object InstalledOn -Descending
|
||||||
|
|
||||||
|
if ($hotFixes.Count -gt 0) {
|
||||||
|
Add-Line ("Most recent update installed: {0}" -f $hotFixes[0].InstalledOn)
|
||||||
|
Add-Line
|
||||||
|
Add-Line 'Installed updates (newest first):'
|
||||||
|
foreach ($hotFix in $hotFixes) {
|
||||||
|
Add-Line (" {0,-12} {1,-14} {2}" -f $hotFix.HotFixID, $hotFix.InstalledOn.ToString('yyyy-MM-dd'), $hotFix.Description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-Line 'No update installation dates were returned by Get-HotFix.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Step 'Writing report'
|
||||||
|
try {
|
||||||
|
$outputDirectory = Split-Path -Parent $OutputPath
|
||||||
|
if ($outputDirectory -and -not (Test-Path -LiteralPath $outputDirectory)) {
|
||||||
|
New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
$report | Out-File -LiteralPath $OutputPath -Encoding utf8 -Force
|
||||||
|
Write-Host (" Report saved to: {0}" -f $OutputPath) -ForegroundColor Green
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Progress -Activity 'Collecting system information' -Completed
|
||||||
|
throw "Could not write the report to '$OutputPath': $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Step 'Opening report in Notepad'
|
||||||
|
try {
|
||||||
|
Start-Process -FilePath 'notepad.exe' -ArgumentList "`"$OutputPath`""
|
||||||
|
Write-Host ' Report opened in Notepad.' -ForegroundColor Green
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Warning ("Could not open Notepad: {0}" -f $_.Exception.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Progress -Activity 'Collecting system information' -Completed
|
||||||
|
Write-Host 'System information collection complete.' -ForegroundColor Green
|
||||||
Reference in New Issue
Block a user