Короче говоря, вот обходной путь. Вы можете определить условные задачи или условный вывод следующим образом:
---
- hosts: windows
tasks:
- name: Execute the PowerShell Script that returns a -ve return code
win_command: powershell .\ps_file_create.ps1
args:
chdir: '%USERPROFILE%\Documents'
register: win_ps_out
ignore_errors: true
- name: Conditional task for positive rc
debug:
msg: "PowerShell rc: {{ win_ps_out.rc }}"
when: win_ps_out.rc <= 2147483647
- name: Conditional task for negative rc
debug:
msg: "PowerShell rc: {{ win_ps_out.rc - 4294967296 }}"
when: win_ps_out.rc > 2147483647
- name: Conditional output
debug:
msg: "PowerShell rc: {% if win_ps_out.rc > 2147483647 %}{{ win_ps_out.rc - 4294967296 }}{% else %}{{ win_ps_out.rc }}{% endif %}"
Вывод для кода возврата 42:
TASK [Conditional task for positive rc] ****************************************
ok: [192.168.0.200] => {
"msg": "PowerShell rc: 42"
}
TASK [Conditional task for negative rc] ****************************************
skipping: [192.168.0.200]
TASK [Conditional output] ******************************************************
ok: [192.168.0.200] => {
"msg": "PowerShell rc: 42"
}
И для кода возврата -99:
TASK [Conditional task for positive rc] ****************************************
skipping: [192.168.0.200]
TASK [Conditional task for negative rc] ****************************************
ok: [192.168.0.200] => {
"msg": "PowerShell rc: -99"
}
TASK [Conditional output] ******************************************************
ok: [192.168.0.200] => {
"msg": "PowerShell rc: -99"
}
Фон
Код возврата, указанный в вопросе, является "правильным". Двоичное представление отрицательного целочисленного значения обычно вычисляется методом two'splement . Например, двоичное представление -99 (использующее 32 бита):
1111 1111 1111 1111 1111 1111 1001 1101
Но, читая эти биты, вы не знаете, представляют ли они отрицательное число в форме дополнения до двух или просто большое положительное число. Вы можете интерпретировать эти биты либо как небольшое отрицательное число -99, либо как большое положительное число 4.294.967.197, которое вы видите в своих выходных данных.
PowerShell возвращает именно те 4 байта, которые показаны выше. Вы можете подтвердить, что PowerShell использует 32-разрядные коды выхода даже в 64-разрядной операционной системе:
PS C:\> [Environment]::Is64BitProcess -and [Environment]::Is64BitOperatingSystem
True
PS C:\> $process = Start-Process powershell -ArgumentList "exit 0xffffffff" -Wait -PassThru
PS C:\> $process.ExitCode
-1
PS C:\> $process = Start-Process powershell -ArgumentList "exit 0x1ffffffff" -Wait -PassThru
PS C:\> $process.ExitCode
0
PS C:\> $process.ExitCode.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Int32 System.ValueType
Вы можете видеть, что код выхода имеет тип Int32
, а также что PowerShell имеет код выхода 0
, если «реальный» код выхода превышает диапазон Int32
.
Так что PowerShell здесь не делает ничего плохого. Пользователь, который оценивает эти 4 байта, должен интерпретировать их как целое число со знаком или без знака. Так что до ansible.
Насколько я знаю, у вас не так много возможностей повлиять ansible на то, как получить результаты от задачи. Для обработки результатов вы можете использовать только фильтры и алгоритмы.
Насколько я знаю, не существует такого типа приведения типов ({{ win_ps_out.rc | int }}
на самом деле является фильтром jinja2, а не приведением типов). И ansible, похоже, не заботится о переменных размерах. Например, ansible не знает int32
или int64
. Просто int
, и это может быть очень большое число, даже большее, чем int64
. Итак, что делает ansible, это берет 4 байта из PowerShell и сохраняет их как целое число с дополнительными - я не знаю, сколько - ведущими нулями. Это будет пример для 64 битов:
0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1001 1101
Теперь это число не может быть интерпретировано как отрицательное число в форме дополнения до двух, потому что самый старший бит установлен в 0
. Это может быть интерпретировано как 4.294.967.197, что происходит в вашем случае.
Теперь вы можете обработать это значение. В верхней части моего ответа я представляю два обходных пути для обработки возвращенного значения и обработки его как целого числа со знаком размером 32 бита.