<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Expert Opinion (Posts about Jenkins)</title><link>http://findlay.space/</link><description></description><atom:link href="http://findlay.space/categories/jenkins.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2020 &lt;a href="mailto:justin@findlay.space"&gt;jmoney&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-NC-SA"
style="border-width:0; margin-bottom:12px;"
src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Fri, 11 Sep 2020 20:35:48 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>A Better Way to a Jenkins Service</title><link>http://findlay.space/posts/a-better-way-to-a-jenkins-service/</link><dc:creator>jmoney</dc:creator><description>&lt;div&gt;&lt;p&gt;The typical way to install a Jenkins service on a Windows system is to download
the JNLP file and then execute the file with Java Web Start&lt;sup&gt;TM -
Oracle: be quite afraid&lt;/sup&gt;.  This process manufactures an excess of anxiety and
annoyance for the user due to dialog boxes and their controls appearing only
upon successful completion of mysterious (magical) events.  Upon failure all
you can do is puzzle about how &lt;a class="reference external" href="http://hrwiki.org/wiki/Ye_Flask"&gt;ye flask may not be got&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to me ye need not wonder, for I will show thou how to get ye flask.
Executing &lt;code class="docutils literal"&gt;javaws&lt;/code&gt; on the Jenkins JNLP file triggers several actions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal"&gt;agent.jar&lt;/code&gt; is downloaded&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal"&gt;WinSW.exe&lt;/code&gt; is downloaded&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the JavaWS window appears, the &lt;code class="docutils literal"&gt;File&lt;/code&gt; menu appears within that window,
and you click on &lt;code class="docutils literal"&gt;Install as Windows Service&lt;/code&gt; in that menu, &lt;code class="docutils literal"&gt;WinSW.exe&lt;/code&gt;
is renamed to the name of the Jenkins service, which is then installed as a
proper Windows service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The new service is started using the &lt;code class="docutils literal"&gt;WinSW.exe&lt;/code&gt; as the service executable
taking its config from a file generated by Jenkins (&lt;code class="docutils literal"&gt;agent.jar&lt;/code&gt; I'm
guessing)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code class="docutils literal"&gt;javaws&lt;/code&gt; process is terminated&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At first you might reason as I did that since the actual Java command line is
configured in the agent config file, that you can just run it directly in a
PowerShell script and install that script as a service.  However, Windows does
not allow services to be defined by script files, only by platform-native
executable files.  One solution to this problem is represented by the popular
&lt;a class="reference external" href="https://nssm.cc/"&gt;NSSM&lt;/a&gt;.  I find Jenkins's own &lt;a class="reference external" href="https://github.com/kohsuke/winsw/"&gt;Windows service wrapper&lt;/a&gt; to be much more elegant as it does not
use an intermediary process.  &lt;code class="docutils literal"&gt;WinSW&lt;/code&gt; merely takes on the name of the service
you want to run by executing the command line provided in its config file.&lt;/p&gt;
&lt;p&gt;Here is the correct way to automate that whole process (guaranteed to get thou
ye flask without any effort):&lt;/p&gt;
&lt;pre class="code sls"&gt;&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-1"&gt;&lt;/a&gt;&lt;span class="cp"&gt;{%&lt;/span&gt;- &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-2"&gt;&lt;/a&gt;    &lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'JenkinsAgent'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-3"&gt;&lt;/a&gt;    &lt;span class="s1"&gt;'service_long_name'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Jenkins Agent (powered by WinSW)'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-4"&gt;&lt;/a&gt;    &lt;span class="s1"&gt;'service_desc'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'This service runs an agent for Jenkins'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-5"&gt;&lt;/a&gt;    &lt;span class="s1"&gt;'service_home'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'C:\\Jenkins'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-6"&gt;&lt;/a&gt;    &lt;span class="s1"&gt;'winsw_uri'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'https://github.com/kohsuke/winsw/releases/download/winsw-v2.2.0/WinSW.NET4.exe'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-7"&gt;&lt;/a&gt;    &lt;span class="s1"&gt;'winsw_sha512'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'f485dec639155528d804bbeddc69a0d9fe77c44444821a5b6cf557ec0b8f9932153a0411bab0524a47f133d2ee5bf3c03830f32b36c77b83cc7f0b1c5a108b33'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-8"&gt;&lt;/a&gt;    &lt;span class="s1"&gt;'jar_sha512'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'6lojuezjazurpmarwmzymthvo0aukur9fvgbiro8gdkkbv7t1ps2nhupdixjcqt1uhzqdzjswojkahulfqbeo5fepuc8ordezt5siugmelxncjwnmggmsvepjufomotk'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-9"&gt;&lt;/a&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-10"&gt;&lt;/a&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-11"&gt;&lt;/a&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-12"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Install &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="c1"&gt;.jar&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-13"&gt;&lt;/a&gt;&lt;span class="nt"&gt;service-downloaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-14"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;file.managed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-15"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_home'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;\\&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;.jar&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-16"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;https://jenkins.mycorp.com/jnlpJars/agent.jar&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-17"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;source_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'jar_sha512'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-18"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;makedirs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;True&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-19"&gt;&lt;/a&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-20"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Setup &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="c1"&gt;.xml&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-21"&gt;&lt;/a&gt;&lt;span class="nt"&gt;service-configured&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-22"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;file.managed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-23"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_home'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;\\&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;.xml&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-24"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p p-Indicator"&gt;|&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-25"&gt;&lt;/a&gt;        &lt;span class="no"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-26"&gt;&lt;/a&gt;          &lt;span class="no"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="no"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-27"&gt;&lt;/a&gt;          &lt;span class="no"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_long_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="no"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-28"&gt;&lt;/a&gt;          &lt;span class="no"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_desc'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="no"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-29"&gt;&lt;/a&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-30"&gt;&lt;/a&gt;          &lt;span class="no"&gt;&amp;lt;executable&amp;gt;java.exe&amp;lt;/executable&amp;gt;  &amp;lt;!-- Should be AdoptOpenJDK version --&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-31"&gt;&lt;/a&gt;          &lt;span class="no"&gt;&amp;lt;arguments&amp;gt;-Xrs -jar "&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_home'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="no"&gt;\\&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="no"&gt;.jar" -jnlpUrl https://jenkins.mycorp.com/computer/&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;grains&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="no"&gt;/slave-agent.jnlp -secret &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;pillar&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;grains&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="o"&gt;]][&lt;/span&gt;&lt;span class="s1"&gt;'jnlp_secret_key'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="no"&gt;&amp;lt;/arguments&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-32"&gt;&lt;/a&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-33"&gt;&lt;/a&gt;          &lt;span class="no"&gt;&amp;lt;logmode&amp;gt;rotate&amp;lt;/logmode&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-34"&gt;&lt;/a&gt;          &lt;span class="no"&gt;&amp;lt;onfailure action="restart" /&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-35"&gt;&lt;/a&gt;        &lt;span class="no"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-36"&gt;&lt;/a&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-37"&gt;&lt;/a&gt;&lt;span class="c1"&gt;# Download, install, and start &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="c1"&gt;.exe&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-38"&gt;&lt;/a&gt;&lt;span class="nt"&gt;service-created&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-39"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;file.managed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-40"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_home'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;\\&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;.exe&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-41"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'winsw_uri'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-42"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;source_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'winsw_sha512'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-43"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;module.run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-44"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;service.create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-45"&gt;&lt;/a&gt;      &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-46"&gt;&lt;/a&gt;      &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;bin_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_home'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;\\&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;.exe&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-47"&gt;&lt;/a&gt;      &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;start_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;auto&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-48"&gt;&lt;/a&gt;      &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;account_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'.\&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;pillar&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'robo_account'&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-49"&gt;&lt;/a&gt;      &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;account_password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;pillar&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'robo_account'&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'pass'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-50"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;unless&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Any changes to the data in this state will require a manual service reinstall because the requisite only checks for existence&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-51"&gt;&lt;/a&gt;      &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="s"&gt;'if&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(Get-Service&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-ErrorAction&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;SilentlyContinue)&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-52"&gt;&lt;/a&gt;         &lt;span class="s"&gt;{&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-53"&gt;&lt;/a&gt;             &lt;span class="s"&gt;Write-Error&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Do&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;not&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;execute&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;because&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;already&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;exists"&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-54"&gt;&lt;/a&gt;         &lt;span class="s"&gt;}'&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-55"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;service.running&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-56"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'service_name'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;a name="rest_code_29279bfdb50d427b85f93f9854b94913-57"&gt;&lt;/a&gt;    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>Jenkins</category><category>SaltStack</category><category>Windows</category><category>WinSW</category><guid>http://findlay.space/posts/a-better-way-to-a-jenkins-service/</guid><pubDate>Fri, 13 Dec 2019 22:24:04 GMT</pubDate></item><item><title>Visual Studio Power Environment: Jenkins Pipeline Edition</title><link>http://findlay.space/posts/visual-studio-power-environment-jenkins-pipeline-edition/</link><dc:creator>jmoney</dc:creator><description>&lt;div&gt;&lt;p&gt;Rather than bother with custom groovy to hack the &lt;a class="reference external" href="https://jenkins.io/doc/book/pipeline/syntax/"&gt;Jenkins declarative pipeline&lt;/a&gt; environment, let's use a
structural paradigm that has been successful for me because of its simplicity
(the only cost being a reusable custom groovy function) and readability (the
function wrapper demonstrates what it does in salutary clarity).&lt;/p&gt;
&lt;pre class="code groovy"&gt;&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-1"&gt;&lt;/a&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;withVSEnvironment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Boolean&lt;/span&gt; &lt;span class="n"&gt;returnStatus&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-2"&gt;&lt;/a&gt;    &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;powershell&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-3"&gt;&lt;/a&gt;        &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-4"&gt;&lt;/a&gt;        &lt;span class="nl"&gt;returnStatus:&lt;/span&gt; &lt;span class="n"&gt;returnStatus&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-5"&gt;&lt;/a&gt;        &lt;span class="nl"&gt;script:&lt;/span&gt; &lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-6"&gt;&lt;/a&gt;&lt;span class="s2"&gt;            foreach (\$_ in cmd /c "`"%VS140COMNTOOLS%`"..\\..\\vc\\bin\\vcvars32.bat &amp;gt; nul 2&amp;gt;&amp;amp;1 &amp;amp; SET") {&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-7"&gt;&lt;/a&gt;&lt;span class="s2"&gt;                if (\$_ -match '^([^=]+)=(.*)') {&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-8"&gt;&lt;/a&gt;&lt;span class="s2"&gt;                    [System.Environment]::SetEnvironmentVariable(\$matches[1], \$matches[2])&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-9"&gt;&lt;/a&gt;&lt;span class="s2"&gt;                }&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-10"&gt;&lt;/a&gt;&lt;span class="s2"&gt;            }&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-11"&gt;&lt;/a&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-12"&gt;&lt;/a&gt;&lt;span class="s2"&gt;            $script&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-13"&gt;&lt;/a&gt;&lt;span class="s2"&gt;        """&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-14"&gt;&lt;/a&gt;    &lt;span class="o"&gt;)&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-15"&gt;&lt;/a&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;returnStatus&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-16"&gt;&lt;/a&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-17"&gt;&lt;/a&gt;    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-18"&gt;&lt;/a&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-19"&gt;&lt;/a&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-20"&gt;&lt;/a&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-21"&gt;&lt;/a&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-22"&gt;&lt;/a&gt;    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-23"&gt;&lt;/a&gt;    &lt;span class="n"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-24"&gt;&lt;/a&gt;        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Stage Left'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-25"&gt;&lt;/a&gt;            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-26"&gt;&lt;/a&gt;                &lt;span class="n"&gt;withVSEnvironment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-27"&gt;&lt;/a&gt;                    &lt;span class="s1"&gt;'Building with PowerShell!!!'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-28"&gt;&lt;/a&gt;                    &lt;span class="n"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// returnStatus&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-29"&gt;&lt;/a&gt;                    &lt;span class="s1"&gt;'''&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-30"&gt;&lt;/a&gt;&lt;span class="s1"&gt;                    # No weak cmd script here&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-31"&gt;&lt;/a&gt;&lt;span class="s1"&gt;                    MSBuild.exe Source/Answer/The_Solution.sln /m /t:Clean,Rebuild&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-32"&gt;&lt;/a&gt;&lt;span class="s1"&gt;                    '''&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-33"&gt;&lt;/a&gt;                &lt;span class="o"&gt;)&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-34"&gt;&lt;/a&gt;            &lt;span class="o"&gt;}&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-35"&gt;&lt;/a&gt;        &lt;span class="o"&gt;}&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-36"&gt;&lt;/a&gt;    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;a name="rest_code_f4ff8a9bee594e0daa66aeff0e696bdd-37"&gt;&lt;/a&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>Batch</category><category>Groovy</category><category>Jenkins</category><category>Microsoft</category><category>PowerShell</category><category>Visual Studio</category><guid>http://findlay.space/posts/visual-studio-power-environment-jenkins-pipeline-edition/</guid><pubDate>Tue, 12 Nov 2019 22:19:59 GMT</pubDate></item><item><title>Visual Studio Power Environment</title><link>http://findlay.space/posts/visual-studio-power-environment/</link><dc:creator>jmoney</dc:creator><description>&lt;div&gt;&lt;p&gt;It is sometimes interesting to speculate about how unusual feature patterns in
Microsoft projects may reflect the traditions or prejudices of the teams
involved with creating and evolving those projects.  Today's example is
&lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;"%VS140COMNTOOLS%"..\..\vc\bin\vcvars32.bat&lt;/span&gt;&lt;/code&gt;, that wily little batch script
that mucks your command environment enough to enable most Visual Studio
declarative-like thingies to happen (easily) on the command prompt.&lt;/p&gt;
&lt;p&gt;So PowerShell has been around for like 17 years now (if you include the Monad
proto period).  That's enough time for an effective rewrite or two of the
Visual Studio codebase and yet we're still stuck with this inconvenient script
written in possibly the worst shell still in popular use today.  How can we get
it to work with possibly the best shell in popular use today?  Unfortunately
there is no single command that will dump the environment of a &lt;code class="docutils literal"&gt;cmd&lt;/code&gt;
subprocess into the parent &lt;code class="docutils literal"&gt;powershell&lt;/code&gt; environment.  I found several hacks
online proposing to do this, the most correct and elegant being
&lt;a class="reference external" href="https://github.com/nightroman/PowerShelf/blob/master/Invoke-Environment.ps1"&gt;Invoke-Environment&lt;/a&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;[Digression] reStructureText's link formatting is &lt;a class="reference external" href="https://stackoverflow.com/questions/4743845/format-text-in-a-link-in-restructuredtext#comment65215146_4836544"&gt;egregiously inferior&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;What I really wanted was some Groovy code that will dynamically modify the
environment of a declarative pipeline with the results of &lt;code class="docutils literal"&gt;vcvars32.bat&lt;/code&gt;.
Jenkins pipeline allows for &lt;a class="reference external" href="https://jenkins.io/doc/book/pipeline/jenkinsfile/#setting-environment-variables-dynamically"&gt;setting environment variables dynamically&lt;/a&gt;,
but the dynamism packaged into this feature only allows for arbitrary values
for a set of &lt;em&gt;a priori&lt;/em&gt; variable names.  The &lt;code class="docutils literal"&gt;vcvars32.bat&lt;/code&gt; script sets an
indeterminate set of variable names.  There may still be a way to do this, but
my Groovy-fu does not show me how to edit the &lt;code class="docutils literal"&gt;env&lt;/code&gt; object at sufficient
introspection.&lt;/p&gt;
&lt;p&gt;Here is the essential functionality of &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;Invoke-Environment&lt;/span&gt;&lt;/code&gt; applied to
&lt;code class="docutils literal"&gt;vcvars32.bat&lt;/code&gt;.  This is what I used to prime the PowerShell environment for
Visual Studio work by pasting the code block directly into the &lt;a class="reference external" href="https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#powershell-powershell-script"&gt;powershell()&lt;/a&gt;
step before executing Visual Studio commands.  This is not the most elegant,
but it is only a few more lines than directly sourcing the batch script and
seems to be the plainest way to absorb its environment.&lt;/p&gt;
&lt;pre class="code powershell"&gt;&lt;a name="rest_code_28bff3c7ea374c6c940e6f6b54354245-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;`"&lt;/span&gt;&lt;span class="s2"&gt;%VS140COMNTOOLS%&lt;/span&gt;&lt;span class="se"&gt;`"&lt;/span&gt;&lt;span class="s2"&gt;..\\..\\vc\\bin\\vcvars32.bat &amp;gt; nul 2&amp;gt;&amp;amp;1 &amp;amp; SET"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;a name="rest_code_28bff3c7ea374c6c940e6f6b54354245-2"&gt;&lt;/a&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_&lt;/span&gt; &lt;span class="o"&gt;-match&lt;/span&gt; &lt;span class="s1"&gt;'^([^=]+)=(.*)'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;a name="rest_code_28bff3c7ea374c6c940e6f6b54354245-3"&gt;&lt;/a&gt;        &lt;span class="no"&gt;[System.Environment]&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;$matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;a name="rest_code_28bff3c7ea374c6c940e6f6b54354245-4"&gt;&lt;/a&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;a name="rest_code_28bff3c7ea374c6c940e6f6b54354245-5"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If you are using this in a Jenkins pipeline, all &lt;code class="docutils literal"&gt;$&lt;/code&gt;'s will need to be
escaped, &lt;code class="docutils literal"&gt;\$&lt;/code&gt;, to signify that they signal PowerShell variables and not
Groovy variables.  Also &lt;code class="docutils literal"&gt;`&lt;/code&gt; is PowerShell's escape character, so &lt;code class="docutils literal"&gt;`"&lt;/code&gt;
is an escaped quote.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</description><category>Batch</category><category>Groovy</category><category>Jenkins</category><category>Microsoft</category><category>PowerShell</category><category>Visual Studio</category><guid>http://findlay.space/posts/visual-studio-power-environment/</guid><pubDate>Fri, 26 Jul 2019 21:41:13 GMT</pubDate></item></channel></rss>