Files
management-scripts/Get-InstalledSoftware.ps1

99 lines
4.4 KiB
PowerShell

## Specify output file to write data to
$CurrentDateTime = Get-Date -Format "yyyyMMddHHmmssffff"
$FILE = "${OutputDirectory}\${CurrentDateTime}_InstalledSoftware.csv"
## Clear content of output file
If ( Test-Path $FILE ) { Clear-Content -Path $FILE -Force }
## Function to append a line to a file
Function Write-LineToFile {
param([Parameter(Mandatory=$true)][string]$Path,[Parameter(Mandatory=$true)][string]$Line)
If ( -not (Test-Path $Path) ) {
Write-Output "Creating file ""${Path}"""
Try { New-Item -Path $Path -ItemType File -Force | Out-Null }
Catch { Write-Error $_.Exception.Message }
}
Try { Add-Content -Path $Path -Value $Line }
Catch { Write-Error $_.Exception.Message }
}
## Function to test whether or not an item has a specified property
Function Test-ItemProperty {
param([Parameter(Mandatory=$true)][string]$Path,[Parameter(Mandatory=$true)][string]$Name)
Try {
$test = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
If (($null -eq $test) -or ($test.Length -eq 0)) { Return $false } Else { Return $true }
}
Catch { Return $false }
}
## Function to retrieve an item property
Function Get-ItemPropertyInfo {
param([Parameter(Mandatory=$true)][string]$Path,[Parameter(Mandatory=$true)][string]$Name)
If ( Test-ItemProperty -Path $Path -Name $Name ) {
$retval = $(Get-ItemProperty -Path $Path).$Name
$retval = $retval -replace ",", " "
## Additional processing for specific properties
Switch ( $Name ) {
## Convert the estimated size into MB
"EstimatedSize" {
$size = [int]$retval
$size = [Math]::Ceiling($size / 1024)
$retval = [string]$size
}
## Convert the date format into YYYY-MM-DD
"InstallDate" {
$origRetval = $retval
## Try to find each type of date string so we can convert it
Switch -Regex ( $retval ) {
'^\d{8}$' { $formatstring = 'yyyyMMdd' }
'^\d{1,2}\\\d{1,2}\\\d{4}$' { $formatstring = 'MM\dd\yyyy' }
'^\d{4}\\\d{1,2}\\\d{1,2}$' { $formatstring = 'yyyy\MM\dd' }
Default { $formatstring = $null }
}
## Make sure $formatstring has a value, if not just try to cast directly to a datetime
Try {
If ( $null -eq $formatstring ) {
$date = [datetime]$retval
} Else {
$date = [datetime]::ParseExact($retval,$formatstring,$null)
}
## Set $retval to a standard datetime format
$retval = $date.ToString('yyyy-MM-dd')
}
Catch { Write-Error $_.Exception.Message; $retval = $origRetval }
}
Default {}
}
}
Else { $retval = "" }
Return $retval
}
## Write the headers to the output file
Write-LineToFile -Path $FILE -Line "Name,Publisher,Version,InstallDate,EstimatedSize(MB),UninstallString,ModifyPath"
## Iterate through all Registry Uninstall keys and build the CSV file of all installed software
ForEach ( $item in $(Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall','HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall') ) {
$DisplayName = Get-ItemPropertyInfo -Path $item.PSPath -Name DisplayName
$DisplayVersion = Get-ItemPropertyInfo -Path $item.PSPath -Name DisplayVersion
$EstimatedSize = Get-ItemPropertyInfo -Path $item.PSPath -Name EstimatedSize
$InstallDate = Get-ItemPropertyInfo -Path $item.PSPath -Name InstallDate
$Publisher = Get-ItemPropertyInfo -Path $item.PSPath -Name Publisher
$UninstallString = Get-ItemPropertyInfo -Path $item.PSPath -Name UninstallString
$ModifyPath = Get-ItemPropertyInfo -Path $item.PSPath -Name ModifyPath
## Write installed software to output file only if it has a name and uninstall/modify path, otherwise discard
If ( -not (($DisplayName -eq "") -and ($UninstallString -eq "") -and ($ModifyPath -eq "")) ) {
$content = "${DisplayName},${Publisher},${DisplayVersion},${InstallDate},${EstimatedSize},${UninstallString},${ModifyPath}"
Write-LineToFile -Path $FILE -Line $content
}
}