1

When I try to get the file using the following path - it fails:

$path = Get-ItemProperty -Path "%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll"

or

$moduleVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll").FileVersion

is there a workaround for this in powershell?

When I specify the "full path" then it works fine, but I am not actually the one in control of what the value is. So I would expect the path to be resolved automatically as when you paste it directly in Explorer.. but it's not happening.

Get-ItemProperty : Cannot find path 'C:\Users\xxxx\Documents\yyyy\%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll' because it does not exist.

EDIT 1: I have tried to apply the Regex fix but it does not work:

    $path = "%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll";
    $path = $path -replace "\%(.*?)\%", '$env:$1'
    $path2 = Get-ItemProperty -Path "%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll" #does not work
    $path3 = Get-ItemProperty -Path "$env:ProgramFiles\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll" #works
    $path4 = Get-ItemProperty -Path $path #does not work

Could somebody explain why path3 works but path4 isn't? the values are the same.. Still trying to make this work.

Alex
  • 4,607
  • 9
  • 61
  • 99

2 Answers2

1

You can expand the ProgramFiles path by using [Environment]::GetEnvironmentVariable("ProgramFiles"). After it you can build the full path using Combine function.

$programFiles = [Environment]::GetEnvironmentVariable("ProgramFiles")
$aspPath = [IO.Path]::Combine($programFiles, "IIS\Asp.Net Core Module\V2\aspnetcorev2.dll")
EylM
  • 5,967
  • 2
  • 16
  • 28
  • 1
    This will work.. However, as was mentioned in a topic - I am not actually in charge of the link. What will I do if tomorrow this variable changes to %UserProfile% or there are going to be several of them? I am currently trying to build some Regex replacement to `$env:XXXX` format. – Alex Jan 20 '20 at 13:00
  • Also note that in order to retrieve the value of an environment variable by name, something like `$env:ProgramFiles` is the simpler, PowerShell-idiomatic solution. Similarly, the PowerShell-idiomatic way of combining paths is to use the `Join-Path` cmdlet. – mklement0 Jan 20 '20 at 15:47
1

PowerShell itself doesn't support cmd.exe-style environment-variable references such as %ProgramFiles% in expandable strings ("..."); the PowerShell equivalent is $env:ProgramFiles.[1]

If the variable name contains special chars., enclose the name in {...}; e.g., ${env:ProgramFiles(x86)}.

Use the System.Environment.ExpandEnvironmentVariables method to expand cmd.exe-style environment-variable references such as %ProgramFiles% that are embedded in a larger string:

$path = [Environment]::ExpandEnvironmentVariables(
  '%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll'
)

Note: References to undefined env. variables are left untouched.

You can also embed the expression above directly in your cmdlet calls, using (...) (formatted for readability):

$path = Get-ItemProperty -Path (
  [Environment]::ExpandEnvironmentVariables(
    '%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll'
  )
)

[1] And if someone gave you a verbatim string containing such references, you'd have to expand the string on demand, which somewhat obscurely works as follows, for instance:
$verbatim = '$env:ProgramFiles\IIS'; $ExecutionContext.InvokeCommand.ExpandString($verbatim)

mklement0
  • 382,024
  • 64
  • 607
  • 775