- name: execute a powershell cmdlet win_shell: Write-Output "hello from Ansible" register: shellout - name: validate result assert: that: - shellout is successful - shellout is changed - shellout.cmd == 'Write-Output "hello from Ansible"' - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - shellout.rc == 0 - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') # assertion disabled since it does not pass on Windows Server 2016 # - shellout.stderr == "" - shellout.stdout == "hello from Ansible\r\n" - shellout.stdout_lines == ["hello from Ansible"] - name: execute a powershell cmdlet with multi-line output that uses environment with embedded quotes win_shell: Write-Output "hello from Ansible"; Write-Output "another line"; Write-Output "yet another line"; Write-Output "envvar was $env:taskvar" environment: taskvar: "o'doyle rules" register: shellout - name: validate result assert: that: - shellout is successful - shellout is changed - shellout.cmd == 'Write-Output "hello from Ansible"; Write-Output "another line"; Write-Output "yet another line"; Write-Output "envvar was $env:taskvar"' - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - shellout.rc == 0 - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') # assertion disabled since it does not pass on Windows Server 2016 # - shellout.stderr == "" - shellout.stdout == "hello from Ansible\r\nanother line\r\nyet another line\r\nenvvar was o'doyle rules\r\n" - shellout.stdout_lines == ["hello from Ansible","another line", "yet another line", "envvar was o'doyle rules"] - name: execute something nonexistent win_shell: bogus_command1234 register: shellout ignore_errors: true - name: validate result assert: that: - shellout is failed - shellout.failed == true # check the failure key explicitly, since failed does magic with RC - shellout is changed - shellout.cmd == 'bogus_command1234' - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - shellout.rc == 1 - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - shellout.stderr is search('not recognized') - shellout.stdout == "" - shellout.stdout_lines == [] - name: execute something with error output win_shell: Write-Error "it broke"; Write-Output "some output" register: shellout - name: validate result assert: that: - shellout is successful - shellout is changed - shellout.cmd == 'Write-Error "it broke"; Write-Output "some output"' - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$') - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - shellout.rc == 0 - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$') - shellout.stderr is search('it broke') - shellout.stdout == "some output\r\n" - shellout.stdout_lines == ["some output"] - name: ensure test file is absent win_file: path: c:\testfile.txt state: absent - name: run with creates, should create win_shell: echo $null >> c:\testfile.txt args: creates: c:\testfile.txt register: shellout - name: validate result assert: that: - shellout is successful - shellout is changed - name: run again with creates, should skip win_shell: echo $null >> c:\testfile.txt args: creates: c:\testfile.txt register: shellout - name: validate result assert: that: - shellout is skipped - shellout.msg is search('exists') - name: get path of pagefile win_shell: | $pagefile = $null $cs = Get-CimInstance -ClassName Win32_ComputerSystem if ($cs.AutomaticManagedPagefile) { $pagefile = "$($env:SystemRoot.Substring(0, 1)):\pagefile.sys" } else { $pf = Get-CimInstance -ClassName Win32_PageFileSetting if ($pf -ne $null) { $pagefile = $pf[0].Name } } $pagefile register: pagefile_path - name: test creates with hidden system file, should skip win_shell: echo test args: creates: '{{pagefile_path.stdout_lines[0]}}' register: shellout when: pagefile_path.stdout_lines|count != 0 - name: validate result assert: that: - shellout is skipped - shellout.msg is search('exists') when: pagefile_path.stdout_lines|count != 0 - name: ensure testfile is still present win_stat: path: c:\testfile.txt register: statout - name: validate result assert: that: - statout.stat.exists == true # https://github.com/ansible/ansible/issues/37967 - name: test creates with file in missing directory win_shell: echo hi args: creates: c:\fakefolder\fakefolder2\fakefile.txt register: shellout - name: validate result assert: that: - shellout.skipped is not defined - shellout.changed - name: run with removes, should remove win_shell: Remove-Item c:\testfile.txt args: removes: c:\testfile.txt register: shellout - name: validate result assert: that: - shellout is successful - shellout is changed - name: run again with removes, should skip win_shell: echo $null >> c:\testfile.txt args: removes: c:\testfile.txt register: shellout - name: validate result assert: that: - shellout is skipped - shellout.msg is search('does not exist') - name: run something with known nonzero exit code win_shell: exit 254 register: shellout ignore_errors: true - name: validate result assert: that: - shellout is failed - shellout.failed == True # check the failure key explicitly, since failed does magic with RC - shellout.rc == 254 - name: run something via cmd that will fail in powershell win_shell: echo line1 & echo.line2 args: executable: cmd register: shellout - name: validate result assert: that: - shellout is successful - shellout is changed - shellout.rc == 0 - shellout.stdout == "line1 \r\nline2\r\n" - shellout.stdout_lines == ["line1 ", "line2"] - shellout.stderr == "" - name: test with job to ensure that preamble-free InputEncoding is working win_shell: Start-Job { echo yo } | Receive-Job -Wait register: shellout - name: check job result assert: that: - shellout is successful - shellout.stdout_lines[0] == 'yo' - name: interleave large writes between stdout/stderr (check for buffer consumption deadlock) win_shell: $ba = New-Object byte[] 4096; (New-Object System.Random 32).NextBytes($ba); $text = [Convert]::ToBase64String($ba); Write-Output startout; Write-Error starterror; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Output doneout Write-Error doneerror register: shellout - name: ensure that the entirety of both streams were read assert: that: - shellout.stdout is search("startout") - shellout.stdout is search("doneout") - shellout.stderr is search("starterror") - shellout.stderr is search("doneerror") - name: run stdin test win_shell: '$string = [Console]::In.ReadToEnd(); Write-Output $string.Trim()' args: stdin: some input register: shellout - name: assert run stdin test assert: that: - shellout is changed - shellout.rc == 0 - shellout.stderr == "" - shellout.stdout == "some input\r\n"