<p>I have a powershell script, that take my variable and deliver it to the my helm upgrade command</p>
<pre><code>param
(   
    [Parameter(Mandatory = $false)]
    $HELM_SET
)
    helm upgrade --install myrelease -n dev my_service.tgz $HELM_SET 
</code></pre>
<p>My HELM_SET var contains:<br />
<code>--set config.vali=x --set config.spring=v1</code></p>
<p>But helm said after upgrade:
Error: unknown flag: --set config.vali
helm.go:88: [debug] unknown flag: --set config.vali</p>
<p>if i'm add &quot;--set&quot; into
<code>helm upgrade --install myrelease -n dev my_service.tgz --set $HELM_SET </code>
and my HELM_SET var now contains:
<code>config.vali=x --set config.spring=v1</code></p>
<p>after upgrade i receive that my config:vali var is <code>x --set config.spring=v1</code></p>
<p>Can someone explain me what i'm doing wrong?</p>

Сергей Нешитов

<p><strong>If you're passing <code>$HELM_SET</code> as a <em>single string</em> encoding <em>multiple arguments</em>, you cannot pass it as-is to a command</strong>.</p>
<p>Instead, you'll need to parse this string into an <em>array</em> of <em>individual</em> arguments.</p>
<p>In the <strong><em>simplest</em> case</strong>, using the unary form of the <a href="https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Split" rel="nofollow noreferrer"><code>-split</code> operator</a>, which splits the string into an array of tokens by whitespace:</p>
<pre class="lang-sh prettyprint-override"><code>helm upgrade --install myrelease -n dev my_service.tgz (-split $HELM_SET)
</code></pre>
<p>However, <strong>if your arguments include <em>quoted strings</em></strong> (e.g. <code>--set config.spring=&quot;v 1&quot;</code>), more work is needed, because the quoted strings must be recognize as such, so as not to break them into multiple tokens by their <em>embedded</em> whitespace:</p>
<pre class="lang-sh prettyprint-override"><code># Note: Use of Invoke-Expression is safe here, but should generally be avoided.
$passThruArgs = (Invoke-Expression ('Write-Output -- ' + $HELM_SET -replace '\$', &quot;`0&quot;)) -replace &quot;`0&quot;, '$$'

helm upgrade --install myrelease -n dev my_service.tgz $passThruArgs
</code></pre>
<p>See <a href="https://stackoverflow.com/a/67423062/45375">this answer</a> for an explanation of this technique.</p>
<hr />
<p><strong>If you control the <em>invocation</em> of your script, a <em>simpler solution</em> is available:</strong></p>
<p>As <a href="https://stackoverflow.com/users/15339544/santiago-squarzon">Santiago Squarzon</a> points out, you can use the <code>ValueFromRemainingArguments</code> property of a parameter declaration to collect all arguments (that aren't bound to other parameters):</p>
<pre class="lang-sh prettyprint-override"><code>param
(   
    [Parameter(ValueFromRemainingArguments)]
    $__passThruArgs # Choose an exotic name that won't be used in the actual arguments
)

helm upgrade --install myrelease -n dev my_service.tgz $__passThruArgs
</code></pre>
<p>Instead of passing the pass-through arguments <em>as a single string</em>, you would then pass them <em>as individual arguments</em>:</p>
<pre class="lang-sh prettyprint-override"><code>./yourScript.ps1 --set config.vali=x --set config.spring=v1
</code></pre>
