title: How do I set a Machine environment variable from a Chocolatey package?
body: <p>I'm the author of several Chocolatey packages that need to set environment variables as part of the proper "installation" of the package. For example: <code>ANT_HOME</code>, <code>MW_HOME</code>, and <code>JAVA_HOME</code> in the Java ecosystem should point to the installation directory for ant, weblogic, and java, respectively.</p>
  
  <p>And, since Chocolatey is a machine-wide package manager, my thought would be to set these machine-wide (<a href="http://msdn.microsoft.com/en-us/library/96xafkes%28v=vs.110%29.aspx" rel="nofollow">MSDN</a>).</p>
  
  <pre><code>[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "path/to/jre/install", "Machine")
  </code></pre>
  
  <p>If I just run that, I get the expected permission exception</p>
  
  <blockquote>
    <p>Exception calling "SetEnvironmentVariable" with "3" argument(s): "Requested registry access is not allowed."</p>
  </blockquote>
  
  <p>If I run the same command in an elevated prompt, manually, everything works fine. So, I need to invoke it in an elevated prompt. With Chocolatey, you're supposed to use: <code>[Start-ChocolateyProcessAsAdmin][2]</code> like so</p>
  
  <pre><code>Start-ChocolateyProcessAsAdmin @"
  [System.Environment]::SetEnvironmentVariable("JAVA_HOME", "path/to/jre/install", "Machine")
  "@
  </code></pre>
  
  <p>It prompts for elevation (I always run in a normal prompt when developing to be sure that it's actually working), but I see red errors flash by and this message with no warning/error</p>
  
  <blockquote>
    <p>Elevating Permissions and running C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy unrestricted -Command "&amp; import-module -name  'C:\Chocolatey\chocolateyinstall\helpers\chocolateyInstaller.psm1'; try{[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "path/to/jre/install", "Machine"); start-sleep 6;}catch{write-error 'That was not sucessful';start-sleep
     8;throw;}". This may take awhile, depending on the statements.</p>
  </blockquote>
  
  <p>What gives?</p>
  
  <hr>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Some combination of the following makes it work, mysteriously... adding line-terminators (even to single statements) and wrapping all the arguments in single quotes.</p>
  
  <pre><code>Start-ChocolateyProcessAsAdmin @"
  [System.Environment]::SetEnvironmentVariable('JAVA_HOME', 'path/to/jre/install', 'Machine');
  "@
  </code></pre>
  
  <p>I would still like a non-brute-force answer. I'm sure it's a combination of PowerShell's nightmare string quoting/interpreting rules + Chocolatey's invocation.</p>
  
  <hr>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>I'm also having trouble with multiple statements, even though I'm separating them!</p>
  
  <pre><code>Start-ChocolateyProcessAsAdmin @"
  [System.Environment]::SetEnvironmentVariable('MW_HOME', 'path/to/wl/install', 'Machine');
  [System.Environment]::SetEnvironmentVariable('WL_HOME', 'path/to/wl/install/wlserver', 'Machine');
  "@
  </code></pre>
  
  <p>I saw, but did not capture, a Chocolatey log statement on screen that showed one of the line-terminators removed!</p>
  
  <hr>
  
  <p><strong>THOUGHT:</strong></p>
  
  <p>I mean, should I just not do this and write an easy "User" environment variable instead? It's not correct! The damn things are installed machine-wide... I don't want to give up yet.</p>