[SOLVED] Problem with run_powershell_from_file

Questions about WAPT Packaging / Requests and help regarding Wapt packages.
Forum Rules
Community Forum Rules
* English support on www.reddit.com/r/wapt
* French community support is available on this forum
* Please prefix the topic title with [RESOLVED] if it is resolved.
* Please do not edit a topic that is tagged [RESOLVED]. Open a new topic referencing the old one.
* Specify the installed WAPT version, full version, and build number (2.2.1.11957 / 2.2.2.12337 / etc.) as well as the Enterprise/Discovery edition.
* Versions 1.8.2 and earlier are no longer supported. The only questions accepted regarding version 1.8.2 are related to upgrading to a supported version (2.1, 2.2, etc.).
* Specify the server OS (Linux/Windows) and version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Specify the OS of the administration/package creation machine and the machine with the problematic agent, if applicable (Windows 7/10/11/Debian 11/etc.).
* Avoid asking multiple questions when opening a topic, otherwise it may be ignored. If there are multiple topics, open separate topics, preferably one after the other and not all at the same time (i.e., do not spam the forum).
* Include code snippets, screenshots, and other images directly in the post. Links to Pastebin, Bitly, and other third-party sites will be systematically removed.
* As with any community forum, support is provided voluntarily by members. If you require commercial support, you can contact Tranquil IT's sales department at 02.40.97.57.55
Locked
Cédric Morin
Messages: 3
Registration: July 2, 2021 - 10:42

July 2, 2021 - 10:59

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)
User avatar
dcardon
WAPT Expert
Messages: 1932
Registration: June 18, 2014 - 09:58
Location: Saint Sébastien sur Loire
Contact :

July 7, 2021 - 10:33

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
Denis Cardon - Tranquil IT
Share your experiences on WAPT! Send us your blog and article URLs in the "Your Opinion of the forum, and we'll feature them on the WAPT
User avatar
dcardon
WAPT Expert
Messages: 1932
Registration: June 18, 2014 - 09:58
Location: Saint Sébastien sur Loire
Contact :

July 7, 2021 - 5:02 PM

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
Denis Cardon - Tranquil IT
Share your experiences on WAPT! Send us your blog and article URLs in the "Your Opinion of the forum, and we'll feature them on the WAPT
Cédric Morin
Messages: 3
Registration: July 2, 2021 - 10:42

July 8, 2021 - 11:50

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.
Cédric Morin
Messages: 3
Registration: July 2, 2021 - 10:42

July 20, 2021 - 10:19

Hello,

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

Thank you!
Locked