How to create a function in Powershell script?
OK, lets do this. Functions are about avoiding duplicate code which can be done on several levels here. Functions in PowerShell need to be declared before they are executed, so I tend to cluster all functions at the beginning of the script, like this:
# *** FUNCTION DEFINITIONS
function Log-InstalledProgram($InstalledProgram, $LogFilePath)
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $LogFilePath -Value "Product Name: $logString" -Force
add-content -Path $LogFilePath -Value "Publisher: $logp" -Force
add-content -Path $LogFilePath -Value "Version: $logv" -Force
add-content -Path $LogFilePath -Value "InstallDate: $logd" -Force
add-content -Path $LogFilePath -Value "`n" -Force
}
# *** BEGIN MAIN SCRIPT
Clear-Host
#$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$scriptPath = $PSScriptRoot
$logFilePath= Join-path $scriptPath "TestResults.log"
#If log file exists, then clear its contents
if (Test-Path $logFilePath)
{
clear-content -Path $logFilePath
}
$log = "Date Of Testing: {0} " -f (Get-Date)
$logString = "Process Started."
add-content -Path $logFilePath -Value $log -Force
add-content -Path $logFilePath -Value $logString -Force
add-content -Path $logFilePath -Value "`n" -Force
#Validate ADD/Remove Program list
add-content -Path $logFilePath -Value "`n" -Force
add-content -Path $logFilePath -Value "Add/Remove Programs :" -Force
add-content -Path $logFilePath -Value "`n" -Force
$InstalledPrograms = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
add-content -Path $logFilePath -Value "`n" -Force
foreach ($InstalledProgram in $InstalledPrograms )
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Operational Control")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Management Studio")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("System Analyzer")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("STeP")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
}
You can reduce the code further with adding an inner loop for the wanted programs:
foreach ($InstalledProgram in $InstalledPrograms )
{
foreach ($displayName in "Operational Control","Management Studio", "System Analyzer", "STeP")
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains($displayName)))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
}
}
There are other optimizations, for example you could avoid the repeated calls to Add-Content
because the -Value
parameter also takes an array as parameter, you could use a hashtable to capture the object properties you want to extract with their display names in the log file and so on.
SRP
Updated on July 18, 2022Comments
-
SRP almost 2 years
How to write a function to avoid Repeated code for my powershell script, which basically display list of application installed on my machine from Add and Remove window present in control panel.
Below is the powershell script
Stack.ps1
Clear-Host #$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition $scriptPath = $PSScriptRoot $logFilePath= Join-path $scriptPath "TestResults.log" #If log file exists, then clear its contents if (Test-Path $logFilePath) { clear-content -Path $logFilePath } $log = "Date Of Testing: {0} " -f (Get-Date) $logString = "Process Started." add-content -Path $logFilePath -Value $log -Force add-content -Path $logFilePath -Value $logString -Force add-content -Path $logFilePath -Value "`n" -Force #Validate ADD/Remove Program list add-content -Path $logFilePath -Value "`n" -Force add-content -Path $logFilePath -Value "Add/Remove Programs :" -Force add-content -Path $logFilePath -Value "`n" -Force $InstalledPrograms = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* add-content -Path $logFilePath -Value "`n" -Force foreach ($InstalledProgram in $InstalledPrograms ) { if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Operational Control"))) { $InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize $logString = $InstalledProgram.DisplayName $logp = $InstalledProgram.Publisher $logv = $InstalledProgram.DisplayVersion $logd= $InstalledProgram.InstallDate add-content -Path $logFilePath -Value "Product Name: $logString" -Force add-content -Path $logFilePath -Value "Publisher: $logp" -Force add-content -Path $logFilePath -Value "Version: $logv" -Force add-content -Path $logFilePath -Value "InstallDate: $logd" -Force add-content -Path $logFilePath -Value "`n" -Force**** } if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Management Studio"))) { $InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize $logString = $InstalledProgram.DisplayName $logp = $InstalledProgram.Publisher $logv = $InstalledProgram.DisplayVersion $logd= $InstalledProgram.InstallDate add-content -Path $logFilePath -Value "Product Name: $logString" -Force add-content -Path $logFilePath -Value "Publisher: $logp" -Force add-content -Path $logFilePath -Value "Version: $logv" -Force add-content -Path $logFilePath -Value "InstallDate: $logd" -Force add-content -Path $logFilePath -Value "`n" -Force } if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("System Analyzer"))) { $InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize $logString = $InstalledProgram.DisplayName $logp = $InstalledProgram.Publisher $logv = $InstalledProgram.DisplayVersion $logd= $InstalledProgram.InstallDate add-content -Path $logFilePath -Value "Product Name: $logString" -Force add-content -Path $logFilePath -Value "Publisher: $logp" -Force add-content -Path $logFilePath -Value "Version: $logv" -Force add-content -Path $logFilePath -Value "InstallDate: $logd" -Force add-content -Path $logFilePath -Value "`n" -Force } if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("STeP"))) { $InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize $logString = $InstalledProgram.DisplayName $logv = $InstalledProgram.DisplayVersion $logd= $InstalledProgram.InstallDate add-content -Path $logFilePath -Value "Product Name: $logString" -Force add-content -Path $logFilePath -Value "Version: $logv" -Force add-content -Path $logFilePath -Value "InstallDate: $logd" -Force add-content -Path $logFilePath -Value "`n" -Force } }
I am talking about the code present under each if Statements that is used to copy the Output to log file. Can i replace that code with function and call the function in each if statement.
-
SRP over 6 yearsHey @TToni thank you for your help.This is exactly what i wanted and i will also work on your suggestion to avoid repeated calls to Add-Content.
-
TToni over 6 years@SurajPardeshi: In that case would you mind marking this answer as "accepted" and maybe give it an upvote, too?
-
SRP over 6 yearsYa sure Done :-)