Optimization of PS script (Get-Hotfix)

Could you please help me in optimizing the following script (goal of the script: detemine date of last hotfix):

(Get-HotFix | Sort-Object -Property InstalledOn)[-1] | out-file -LiteralPath "d:\temp\ms_update.log"  -Width 160 -Encoding ASCII -Force
(gc "d:\temp\ms_update.log") | ? {$_.trim() -ne "" } | Select-String  -pattern ":" | set-content "d:\temp\ms_update.log"
$lastline = [IO.File]::ReadAllText("d:\temp\ms_update.log")

  • How to transform it into a script not using a workfile?

  • How can I include -ErrorAction SilentlyContinue?

  • How to handle a status where no hotfixes are installed yet?

  • General question: Is there a general solution to delete empty lines from any output (e.g. Get-CimInstance) without using a workfile?

Many thanks - Michael

There should not be a need for using a temp file for this request. Everything can be done in memory.

$HotFixes = Get-HotFix
if($HotFixes) { //True if there are results [not empty]
    ($HotFixes | Sort-Object -Property InstalledOn -Desc)[0].InstalledOn

This will return a long datatime formatted string. If you prefer a short date you can wrap the ($HotFixes line in another set of parenthesis and add .ToShortDateString()

Thanks! But how to handle the operations on the result without having a file:

delete empty lines
$lastline = [IO.File]::ReadAllText("d:\temp\ms_update.log")


He just showed you how to pull the latest date without a file. Did you even try his suggestion? My advice to you is stop treating powershell like text. Powershell works with objects. You keep turning it into text and outputting it vs extracting the info you desire from the rich objects at your disposal

Yes - neemober’s suggestions works fine and yes: I am comng from FORTRAN / batch programminf and thus do not thi´ink object-orieented until now.

The goal of the script (as it is called by batch) is to set the exit-code to $lastdate. Is there any way to perform this “object-poriented”?

Thanks - Michael

PowerShell is object oriented as is the code I suggested. You can call that code without a batch script if I am understanding you correctly. Also it’s returning the date, so unsure why it needs to be stored as an exit code which is an integer value only

My explanation was “a little bit wrong”: The calling batch needs the difference in days between two dates (which is an integer).
Why calling PS from batch: I have a batch based system grown in 20 years and try to switch step by step to Powershell. Doing this in ne big step is not possible due to my capacities.

Thanks - Michael

So you need the difference between what two dates?

My script is running and gives the correct result (true/false dependent on the nummer of days since last hotfix):

	[string]$Days ="",
	[string]$Workfile =""

(Get-HotFix | Sort-Object -Property InstalledOn)[-1] | out-file -LiteralPath "$Workfile"  -Width 160 -Encoding ASCII -Force 
(gc "$Workfile") | ? {$_.trim() -ne "" } | Select-String  -pattern ":" | set-content "$Workfile"
$lastline = [IO.File]::ReadAllText("$Workfile") 
$datum=-(New-TimeSpan -End $lastdate)
if ($AnzahlTage -gt $Days) {exit 0} else {exit 1}

but: It looks old-fashioned (specially the usage of a workfile)

Thanks - Michael

This returns the number of days since the last patch

$HotFixes = Get-HotFix
if($HotFixes) {
    $LastHotFixDate = ($HotFixes | Sort-Object -Property InstalledOn -Desc)[0].InstalledOn
    (New-TimeSpan -Start $LastHotFixDate -End (Get-Date)).Days

Great support! This will help me much on my way to object oriented thinking / programming.

Thanks again - Michael