PowerShell - 运行 bat/cmd 文件后获取环境变量

问题描述 投票:0回答:1

我想从 powershell 运行一个 cmd 文件并通过该 cmd 文件检索一个设置的变量

我的脚本返回一个 null/空变量

Start-Process -FilePath "cmd.exe" -ArgumentList "/c 'my.cmd'" -Wait
$envVariable = [System.Environment]::GetEnvironmentVariable("my-variable", [System.EnvironmentVariableTarget]::Process)
Write-Host "Environment Variable Value: $envVariable"

.cmd 文件包含这样的行

set my-variable=2.6.4.6

如何从 powershell 获取该值?

感谢您的帮助

powershell batch-file environment-variables
1个回答
0
投票

问题

  • 仅当您的批处理创建了持久

    环境变量(即存储在注册表中的环境变量,例如:通过
    [System.Environment]::GetEnvironmentVariable()
    相比之下,

    setx.exe
  • 的内部
  • cmd.exe

    命令创建

    进程范围
    环境变量,即它们仅为
    当前进程
    定义。 因为 PowerShell 必须在

    子进程
  • 中运行批处理文件(
  • SET

    *.cmd
    )(通过
    *.bat
    隐式),所以它无法查询由批处理文件创建的进程级环境变量:当调用返回时,批处理文件进程已退出,并且其进程特定的环境变量不再存在。
    
    

    一个
  • 潜在的解决方案

假设您的批处理文件在

cmd.exe

设置其环境变量之前使用SETLOCAL - 如果其目的是为托管

SET
会话设置环境变量,则会出现这种情况 - 您可以使用以下方法:
通过

cmd.exe
    CLI (
  • cmd.exe

    ) 调用批处理文件,并在调用后单独使用

    cmd /c
    命令,该命令会列出执行批处理文件后的所有进程级环境变量。
    
    
    您可以捕获此列表并将其与 

    PowerShell
  • 看到的进程级环境变量进行比较,这会告诉您添加或更新了哪些变量,甚至删除了哪些变量。
  • 注意:下面仅关注 added

      updated
    • 变量;还需要做更多的工作来传播环境变量的removal
    • SET
  • 注:

上面的

丢弃
    批处理文件自己的(标准输出)输出,假设它不感兴趣,这也简化了处理。如果您希望该输出
  • 通过

    (或者,如果您相应地调整下面的代码以单独捕获它),请使用以下代码片段代替上面的单个# Get the current list of env. vars. and their values, in the same # format that cmd.exe's SET command produces. $envVarsBefore = Get-ChildItem env: | ForEach-Object { '{0}={1}' -f $_.Name, $_.Value } # Synchronously execute the batch file and call SET from the same cmd.exe # session to list all process-level env. vars. # For robustness, a GUID is used to separate the batch file's own output from # that of the SET command. # NOTE: # * For simplicity, the batch file's own output is *discarded* (>NUL) # See the notes below this code if you want to pass it through. # * "PROMPT" is excluded, as it is only relevant to cmd.exe $envVarsAfter = cmd /c 'my.cmd >NUL & SET' | Where-Object { $_ -notmatch '^PROMPT=' } # Now compare the two lists and define the variables in PowerShell # that were added or updated by the batch file. Compare-Object -PassThru $envVarsBefore $envVarsAfter | Where-Object SideIndicator -eq '=>' | # variable was added or updated ForEach-Object { # Split the "<name>=<value>" line into the variable's name and value. $name, $value = $_ -split '=', 2 # Define it as a process-level environment variable in PowerShell. Set-Item Env:$name $value } 语句: $envVarsAfter = ...

    
    

© www.soinside.com 2019 - 2024. All rights reserved.