Page 1 of 1

[SOLVED] Problem with run_powershell_from_file

Published: July 2, 2021 - 10:59 AM
by Cédric Morin
Good morning,

I'm having a small problem with the setup helpers run_powershell_from_fileI wrote my script in PowerShell and it doesn't seem to have any problems running.

Code: Select all

#Script pour determiner si Nuget est installé et dans quelle version

Try{
    $Version = (Get-PackageProvider -Name "Nuget" -ErrorAction SilentlyContinue).Version
    $Result = "NuGet found. Version : $($Version.ToString())"
}
Catch{
    $Result = "NuGet not found."
}

$Result
When I feed my audit function this:

Code: Select all

run_powershell_from_file("Get-INSANugetVersion.ps1",output_format='json')
I'm getting a big error message:

Code: Select all

Auditing c:\waptdev\insat-nuget_x64_PROD-wapt\WAPT\.. ...
2021-07-02 10:41:13,071 CRITICAL Fatal error in audit function: CalledProcessErrorOutput: Command '$ProgressPreference = "SilentlyContinue"\n(#Script pour determiner si Nuget est installé et dans quelle version\n\nTry{\n    $Version = (Get-PackageProvider -Name "Nuget" -ErrorAction SilentlyContinue).Version\n    $Result = "NuGet found. Version : $($Version.ToString())"\n}\nCatch{\n    $Result = "NuGet not found."\n}\n\n\n$Result) | ConvertTo-Json' returned non-zero exit status 1.
Output:#< CLIXML
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><S S="Error">Au caractère Ligne:7 : 2_x000D__x000A_</S><S S="Error">+ }_x000D__x000A_</S><S S="Error">+  ~_x000D__x000A_</S><S S="Error">Parenthèse fermante « ) » manquante dans l'expression._x000D__x000A_</S><S S="Error">Au caractère Ligne:8 : 1_x000D__x000A_</S><S S="Error">+ Catch{_x000D__x000A_</S><S S="Error">+ ~~~~~_x000D__x000A_</S><S S="Error">Jeton inattendu « Catch » dans l'expression ou l'instruction._x000D__x000A_</S><S S="Error">Au caractère Ligne:13 : 8_x000D__x000A_</S><S S="Error">+ $Result) | ConvertTo-Json_x000D__x000A_</S><S S="Error">+        ~_x000D__x000A_</S><S S="Error">Jeton inattendu « ) » dans l'expression ou l'instruction._x000D__x000A_</S><S S="Error">Au caractère Ligne:13 : 10_x000D__x000A_</S><S S="Error">+ $Result) | ConvertTo-Json_x000D__x000A_</S><S S="Error">+          ~_x000D__x000A_</S><S S="Error">Un élément de canal vide n'est pas autorisé._x000D__x000A_</S><S S="Error">    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException_x000D__x000A_</S><S S="Error">    + FullyQualifiedErrorId : MissingEndParenthesisInExpression_x000D__x000A_</S><S S="Error"> _x000D__x000A_</S></Objs>:

Note that if I put this in the audit, it works as expected:

Code: Select all

    result = run('C:\\Windows\\System32\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -File .\\Get-INSANugetVersion.ps1')
    print(result)

Code: Select all

Ligne de Commande : audit -f "c:\waptdev\insat-nuget_x64_PROD-wapt\WAPT\.."
Using config file: C:\Program Files (x86)\wapt\wapt-get.ini
Auditing c:\waptdev\insat-nuget_x64_PROD-wapt\WAPT\.. ...
NuGet found. Version : 2.8.5.208

c:\waptdev\insat-nuget_x64_PROD-wapt\WAPT\.. -> UNKNOWN
So I don't understand why run_powershell_from_file generates an error, since from the PowerShell console and with run I have no problems?

Thank you for your help!

--------------------------------------------------------------------------------------------------------------------------
- Installed WAPT version: 2.0
- Server OS: Linux Ubuntu 20.04
- Operating system of the administration/package creation machine: Windows 10 (20H2)

Re: Problem with run_powershell_from_file

Published: July 7, 2021 - 10:33 AM
by dcardon
Hi Cédric,
we're using a blob as a parameter because Windows often blocks the loading of PowerShell scripts in .ps1 files. However, I'm surprised the script wasn't converted to base64... I'll submit a ticket internally.
Regards,
Denis

Re: Problem with run_powershell_from_file

Published: July 7, 2021 - 5:02 PM
by dcardon
The script correctly converted to base64 in the code. PowerShell can be quite temperamental. I've made a couple of fixes. You can try replacing the `run_powershell()` function on your test machine with this one to verify that it works. I tested it myself and it worked fine with your script. This will be included in the next release, 2.1.

Sincerely,

Denis

Code: Select all

def run_powershell(cmd, output_format='json', **kwargs):
    """Run a command/script (possibly multiline) using powershell, return output in text format
    If format is 'json', the result is piped to ConvertTo-Json and converted back to a python dict for convenient use

    WARNING: This works only with powershell >= 3

    Args:
        output_format (str): set output format as json (default) or xml (ElementTree object) or text

    Returns:
        str or dict or list

    .. versionadded:: 1.3.9
    """
    if output_format not in ('json','text','xml'):
        raise ValueError("Input parameter output_format not correct (json/text/xml expected: %s" % output_format)


    output_version = run('powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$PSVersionTable.PSVersion.Major"').strip()

    try:
        if int(output_version)<3 :
            raise Exception('run_powershell need powershell version >=3, please install tis-powershell package first')
    except:
        pass

    cmd = ensure_unicode(cmd)

    if output_format == 'json':
        output_format_ps = 'text'
        cmd = '$ProgressPreference = "SilentlyContinue"\n%s  | ConvertTo-Json ' % cmd
    else:
        output_format_ps = output_format
    # command is a utf16 without bom encoded with base64 without \n
    # we should not get stderr so that ouput can be decoded as json. stderr get progress report...
    if not 'return_stderr' in kwargs or not isinstance(kwargs['return_stderr'], list):
        return_stderr = []
    else:
        kwargs.pop('return_stderr')
    try:
        with disable_file_system_redirection():
            cmd = 'powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -OutputFormat %s -EncodedCommand "%s" ' %  (output_format_ps,  base64.b64encode(cmd.encode('utf-16le')).decode('utf-8'))
            logger.debug("running powershell command : \n%s" % cmd)
            result = run(cmd,
                         return_stderr=return_stderr,
                         **kwargs)
    except CalledProcessErrorOutput as e:
        raise CalledProcessErrorOutput(e.returncode, cmd, e.output)

    # remove comments...
    if output_format.lower() == 'xml':
        lines = [l for l in result.splitlines() if not l.strip().startswith('#') and l.strip()]
        import xml.etree.ElementTree as ET
        return ET.fromstringlist(lines)
    elif output_format.lower() == 'json':
        lines = [l for l in ensure_unicode(result).splitlines() if not l.strip().startswith('#')]
        if not lines:
            return None
        else:
            try:
                json_output = json.loads('\n'.join(lines))
                return json.dumps(json_output)
            except ValueError as e:
                raise ValueError('%s returned non json data:\n%s' % (cmd, result))
    else:
        return result

Re: [SOLVED] Problem with run_powershell_from_file

Published: July 8, 2021 - 11:50 AM
by Cédric Morin
Hello,

I'll test this as soon as possible. I hope before the end of the month, we're quite busy at the moment!

Cedric.

Re: [SOLVED] Problem with run_powershell_from_file

Published: July 20, 2021 - 10:19 AM
by Cédric Morin
Hello,

I just did some tests, and it seems to work correctly with the fix!

Thank you!