Home > Back-end >  Powershell passing a parameter as a parameter to another function
Powershell passing a parameter as a parameter to another function

Time:10-18

Can a parameter be passed as a parameter from one function to another?

Get-Version can retrieve the version from an installed package, an exe, or an MSI. I only allow one parameter to be used by using parameter sets.

function Get-Version{
    #returns version of either an installed file, or from an exe or msi path.
    param(
        [Parameter(ParameterSetName="installed")]
        [String]$SoftwareName,
        
        [Parameter(ParameterSetName="exepath")]
        [String]$ExePath,

        [Parameter(ParameterSetName="msipath")]
        [String]$MsiPath
    )
    switch ($PSCmdlet.ParameterSetName) {
        'installed' {
            $version = Get-Package | Where-Object {($_.Name -like $SoftwareName)} | Select-Object -ExpandProperty Version
        }
        'exepath' {
            $version = (Get-Item -path $ExePath).VersionInfo | Select-Object -ExpandProperty ProductVersion
        }
        'msipath' {
            try {
                $FullPath = (Resolve-Path $MsiPath).Path
                $windowsInstaller = New-Object -com WindowsInstaller.Installer

                $database = $windowsInstaller.GetType().InvokeMember(
                        "OpenDatabase", "InvokeMethod", $Null, 
                        $windowsInstaller, @($FullPath, 0)
                    )

                $q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'"
                $View = $database.GetType().InvokeMember("OpenView", "InvokeMethod", $Null, $database, ($q))
                $View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null)
                $record = $View.GetType().InvokeMember("Fetch", "InvokeMethod", $Null, $View, $Null)
                $productVersion = $record.GetType().InvokeMember("StringData", "GetProperty", $Null, $record, 1)

                $View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null)

                $version = $productVersion

            } catch {
                throw "Failed to get MSI file version the error was: {0}." -f $_
            }
        }
    }
    
    if($null -eq $version){
        #throw "Software not found"
        return $null
        return "SOFTWARE NOT FOUND"
    }elseif($version.GetTypeCode() -eq "String"){
        [System.Version]$version
    }else{
        #throw "More Than One Version Found"
        return $null
        return "TOO MANY SOFTWARE VERSIONS FOUND"
    }
}

Update-Software is not completely written yet, it calls Get-Version and I would like to be able to pass the MSIPath or ExePath to Get-Version without using an If statement, if possible.

function Update-Software {
    #checks installed and loaded software versions and returns true/false if it needs to be updated
    param (
        [Parameter(Mandatory=$True)]
        [String]$LocalSoftwareSearchString,
        
        [Parameter(Mandatory=$True)]
        [String]$LoadedSoftwarePath,

        [Parameter(Mandatory=$True)]
        [parameter?]$LoadedSoftwareParamaterType, ##This is where I dont know how to pass a parameter

        [Parameter(Mandatory=$True)]
        [String]$SoftwareDescription
    )


        $verSWInstalled = Get-Version -SoftwareName $LocalSoftwareSearchString
        $verSWLoaded = Get-Version -$LoadedSoftwareParamaterType $LoadedSoftwarePath


        if($verSWInstalled -gt $verSWLoaded){
            #return true
            #return message if upgrade needed
        }else{
            #return false
            #return message if upgrade not needed
        }
}

my ideal function call would look like for an EXE

Update-Software -LocalSoftwareSearchString Office365 -LoadedSoftwarePath D:\Office.exe -LoadedSoftwareParameterType ExePath

and this for an MSI

Update-Software -LocalSoftwareSearchString Office365 -LoadedSoftwarePath D:\Office.msi-LoadedSoftwareParameterType MsiPath

CodePudding user response:

Define your parameter as follows, which limits the values you may pass to it to one of the values specified in the [ValidateSet()] attribute, which here correspond to the relevant parameter names of Get-Version:

      [Parameter(Mandatory=$True)]
      [ValidateSet('SoftwareName', 'ExePath', 'MsiPath')]
      [string] $LoadedSoftwareParameterType, 

Then pass this parameter's value as the parameter name through to Get-Version, and use the -LoadedSoftwarePath parameter's value as its value, via (hashtable-based) splatting:

$htArgs = @{ $LoadedSoftwareParameterType = $LoadedSoftwarePath }

# ...

$verSWLoaded = Get-Version @htArgs

To give a concrete example: The above makes Update-Software, when invoked with
-LoadedSoftwareParameterType ExePath -LoadedSoftwarePath c:\path\to\foo.exe, in effect internally call
Get-Version -ExePath c:\path\to\foo.exe

  • Related