powershell - How to get the value of the PATH environment variable without expanding tokens? -


i'm writing powershell script convert folder names short names in path environment variable , save changes. works correctly explicit paths, expands tokens, when save changes tokens replaced explicit paths. i'd preserve tokens.

for example, if path this: %systemroot%;%systemroot%\system32;c:\program files\tortoisesvn\bin;c:\programdata\chocolatey\bin

i want result: %systemroot%;%systemroot%\system32;c:\progra~1\tortoi~1\bin;c:\progra~3\chocol~1\bin

but instead this: c:\windows;c:\windows\system32;c:\progra~1\tortoi~1\bin;c:\progra~3\chocol~1\bin

here's full script illustrates problem.

# current path. # ended not using either of these approaches because appear # contextual; on system, @ least, include paths aren't # seen when view path value system properties -> environment # variables dialog box. $current_path = $env:path $current_path = [system.environment]::getenvironmentvariable("path")  # instead, path value directly registry, so: $current_path = (get-itemproperty -path 'hklm:\system\currentcontrolset\control\session manager\environment' -name path).path  # problem powershell expands tokens when reading  # registry, can't detect tokens , ignore them.  want # literal string value, no token evaluation. # here's sample value; see in regedt32 , system dialogs, # it's not line above. $current_path = '%systemroot%;%systemroot%\system32;c:\program files\tortoisesvn\bin;c:\programdata\chocolatey\bin'  $new_path = ''  # filesystemobject has method convert path using short names folders. $fso = new-object -comobject scripting.filesystemobject  # individual paths delimited semicolon.  skip paths tokens,  # , preserve trailing slashes in each path. $current_path.split(';') |     foreach-object {          if ($_.startswith('%'))             { $_ }         elseif ($_.endswith('\'))             { "$($fso.getfolder($_).shortpath)\" }         else             { "$($fso.getfolder($_).shortpath)" }      } |     foreach-object { $new_path += "$_;" }  # remove semicolon end new path. $new_path = $new_path.trimend(";")  "current path length: $($current_path.length)" "new path length: $($new_path.length)"  $new_path  # commented out don't accidentally update path if try out script #[system.environment]::setenvironmentvariable("path", $new_path, "machine") 

it seems should easy enough if literal string value registry, far have not been able figure out how that.

this isn't powershell per se, "feature" of underlying windows registry. path variable of type reg_expand_sz automatically expands environment variables on retrieval. don't think can around built-in cmdlets, can .net microsoft.win32.registry apis. use registrykey.getvalue overload registryvalueoptions.donotexpandenvironmentnames:

$regkey = [microsoft.win32.registry]::localmachine.opensubkey('system\currentcontrolset\control\session manager\environment', $true) $regkey.getvalue('path', $null, "donotexpandenvironmentnames") 

when time save variable, use overload of setvalue registryvaluekind.expandstring save correct type:

$regkey.setvalue("path", $new_path, "expandstring") 

Comments

Popular posts from this blog

python - Healpy: From Data to Healpix map -

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -