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
Post a Comment