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