2012-01-23 12 views
5

Estoy modificando PATH en varios servidores W2k3 en PowerShell para convertir ciertas rutas con espacios en blanco a sus 8.3 equivalentes. Después de varias transformaciones de expresiones regulares, corro los dos comandos siguientes:¿Cómo manejo la expansión variable de PATH de Windows cuando se configura desde PowerShell?

# Set the path for this process 
$env:PATH = $path 
# Set the path for the Machine 
[System.Environment]::SetEnvironmentVariable('PATH', $path,[System.EnvironmentVariableTarget]::Machine) 

Después de ejecutar ellos, el camino se cambia de una manera que no pretendía. % SystemRoot% se expande uniformemente a C: \ Windows. No puedo ver dónde esto señala el apocalipsis, pero prefiero mantener el% SystemRoot%, así que jugueteé hasta que obtuve% SystemRoot% para que aparezca nuevamente en la ruta, pero cuando lo hago, la ruta ya no se expande y ya no se expande trabajos. Hacer eco de la ruta en la CLI devuelve una cadena no expandida (esto es incorrecto) y los comandos en SystemRoot ya no se pueden encontrar.

Si agrego una entrada nula a la ruta ";;", sin alterar ningún otro texto en la RUTA, comienza a funcionar correctamente.

Así que mi pregunta es cómo modificar la ruta programáticamente usando PowerShell para no ensuciar la expansión variable dentro de la ruta?

+0

2 notas: 1) Abro una nueva CLI para cada prueba, y 2) la ruta que leo desde $ env: PATH se expande, entonces estoy leyendo c: \ windows y cambiando manualmente el valor a% SystemRoot % luego empujando ese valor nuevamente al ambiente. – codepoke

+0

¿Qué hay en '$ path' cuando lo configura en' PATH'? – manojlds

+0

Es diferente en cada servidor, pero ...;% SystemRoot% \ system32;% SystemRoot%;% SystemRoot% \ System32 \ Wbem;% SystemRoot% \ system32 \ WindowsPowerShell \ v1.0; ... es un componente de todos de ellos. Cuando leo $ path, se expande a c: \ Windows durante el proceso de lectura. Tengo que colocar el valor expandido con su equivalente variable antes de configurarlo. Ese valor $ path con variables no se expandirá nuevamente a menos que lo toque manualmente a través del diálogo de propiedades. – codepoke

Respuesta

6

Por lo que puedo decir, no puede hacer esto con el método [Environment]::SetEnvironmentVariable() y no puede hacer esto con el proveedor de registro. Sin embargo se puede acceder a la ruta del sistema env var en el registro utilizando la clase Microsoft.Win32.RegistryKey así:

 
C:\PS> $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true) 
C:\PS> $path = $key.GetValue('Path',$null,'DoNotExpandEnvironmentNames') 
C:\PS> $path 
...;%systemroot%\System32\WindowsPowerShell\v1.0\ 
C:\PS> $key.SetValue('Path', $path + ';%Windir%\Symbols', 'ExpandString') 
C:\PS> $key.Dispose() 

Esto le permitirá guardar la ruta actualizada y preservar las variables que aparecen en el valor Path.

+0

Fabuloso, Keith. Gracias de nuevo. – codepoke

+0

Para su información, la secuencia de comandos probablemente se debe poner en una try/finally y dentro de la Dispose finalmente en la clave de registro. –

+0

Sabes, casi le pregunté sobre esto, pero como mi guión es corto y todas las variables desaparecen de inmediato, no lo suté. Pero desde que lo mencionaste. :-) .NET 4.0 incluye el método Dispose() manual que usted llama, pero 2.0 no. ¿Cómo debo deshacerme de la llave sin un método Dispose()? – codepoke

Cuestiones relacionadas