Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a function in Powershell script?

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.

like image 962
SRP Avatar asked May 09 '26 20:05

SRP


1 Answers

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.

like image 75
TToni Avatar answered May 12 '26 11:05

TToni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!