How to create a function in Powershell script?

16,941

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.

Share:
16,941
SRP
Author by

SRP

Updated on July 18, 2022

Comments

  • SRP
    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
    SRP over 6 years
    Hey @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
    TToni over 6 years
    @SurajPardeshi: In that case would you mind marking this answer as "accepted" and maybe give it an upvote, too?
  • SRP
    SRP over 6 years
    Ya sure Done :-)