Reputation: 3
This function gets a list of installed software on a remote PC. What is special about this function is the conversion of the date from yyyyMMdd
to MM/dd/yyyy
. While the function works, it is dropping objects that have no InstallDate
. I get this error:
Exception calling "ParseExact" with "3" argument(s).
function Get-Software {
param ( [string[]]$ComputerName )
[scriptblock]$code = {
$keys = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
Get-ItemProperty -Path $keys |
Where-Object { $_.DisplayName -ne $null } |
Where-Object { $_.DisplayName -notlike '*update*' } |
sort DisplayName |
ForEach-Object {
[PSCustomObject]@{
Display = $_.DisplayName;
Installed = Get-Date ([DateTime]::ParseExact($_.InstallDate, 'yyyyMMdd', $null)) -format d
}
}
}
Invoke-Command -ScriptBlock $code -ComputerName $ComputerName -ArgumentList * |
ft Display, Installed -AutoSize |
Out-File "$Env:USERPROFILE\Desktop\SWinv.txt"
}
Get-Software RemotePC
What can I do to return all objects?
Upvotes: 0
Views: 418
Reputation: 17472
Because install date can be null, try this
function Get-Software {
param ( [string[]]$ComputerName )
[scriptblock]$code = {
$keys = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
Get-ItemProperty -Path $keys |
Where-Object { $_.DisplayName -ne $null -and $_.DisplayName -notlike '*update*' } |
sort DisplayName |
ForEach-Object {
[PSCustomObject]@{
Display = $_.DisplayName;
Installed =if ($_.InstallDate -ne $null) { Get-Date ([DateTime]::ParseExact($_.InstallDate, 'yyyyMMdd', $null)) -format d} else {$null}
}
}
}
Invoke-Command -ScriptBlock $code -ComputerName $ComputerName -ArgumentList * |
ft Display, Installed -AutoSize |
Out-File "$Env:USERPROFILE\Desktop\SWinv.txt"
}
Get-Software RemotePC
Upvotes: 1
Reputation: 200393
Do the date parsing in a try..catch
, assign the result to a variable, and use that variable when creating the object:
... | ForEach-Object {
$date = try {
[DateTime]::ParseExact($_.InstallDate, 'yyyyMMdd', $null).ToString('d')
} catch {
'' # default value to assign if date is invalid
}
[PSCustomObject]@{
Display = $_.DisplayName;
Installed = $date
}
}
Upvotes: 1
Reputation: 10044
You could put a simple if/else check.
Assuming that $_.InstallDate is null when you get the error:
ForEach-Object {
if ($null -ne $_.InstallDate) {
[PSCustomObject]@{Display = $_.DisplayName; Installed = Get-Date ([datetime]::ParseExact($_.InstallDate,'yyyyMMdd',$null)) -format d}
} else {
[PSCustomObject]@{Display = $_.DisplayName; Installed = "Not Available"}
}
}
Upvotes: 1