unit 8 · Windows track
become, runas & Windows paths
Elevation without sudo, backslashes without tears
you may want to read 13 · YAML pitfalls & the quoting rule , 30 · Windows connections: WinRM, PSRP, SSH first — but nothing is locked
tl;dr
- On Windows, become means become_method: runas — a fresh logon as become_user, not a sudo wrapper.
- become also bypasses WinRM restrictions (WUA, DPAPI, non-interactive limits) — key for lesson 35.
- Double-quoted "C:\temp" turns \t into a tab. Single-quote Windows paths and backslashes stay literal.
why it matters Half the mystery Windows failures — access denied, updates refusing to install, paths with tabs in them — trace back to runas and quoting, not to the module you blamed.
On Linux, become: true quietly means sudo. Windows has no sudo, but
become still works. The method underneath changes to
runas , and it behaves less like a sudo prefix than like
something you already know: a brand-new logon session, created for
the task, carrying become_user’s token.
- name: Show who the task really runs as
ansible.windows.win_shell: whoami /all # user, groups, privileges
become: true
become_method: runas # the Windows become method
become_user: svc_deploy # fresh logon as this account
vars:
ansible_become_password: '{{ vault_deploy_password }}' # lesson 27Two mechanics. First, unlike sudo, runas generally wants the
target account’s password — supplied as ansible_become_password,
vaulted, never plaintext. Built-in service accounts (SYSTEM and friends)
need none. Second, creating that logon requires SeDebugPrivilege on
the connecting account. Administrators have it by default, so it only
bites when Ansible gets a deliberately stripped-down account — then runas
fails before your task starts.
UAC gets a vote too. Runas asks for the full elevated token. If the account can’t elevate, it falls back to the limited token — the task still runs, minus the admin half of its group memberships. Same split-token dance as “Run as administrator”, performed non-interactively.
The side effect that matters more than elevation
A WinRM session is a network, non-interactive logon. Several Windows components flatly refuse to work in one: the Windows Update Agent, DPAPI (anything that decrypts stored secrets), installers demanding an interactive session. Your module is fine; the logon type is the problem.
become fixes this, because a runas logon isn’t a network logon. The official
docs are explicit: become can bypass all WinRM restrictions — WUA, DPAPI, the non-interactive limits. On Windows, become
has two jobs: changing who runs the task, and changing what
kind of logon runs it. The second job is useful even when become_user
is the same account you connected as.
Plant this deep — it returns next lesson. When a task reaches from the
target to a second machine (a file share, a domain controller), the
network logon fails in a uniquely maddening way. become is one of the
official fixes.
Backslashes: lesson 13, Windows edition
Lesson 13’s quoting rule gets a Windows extension. In YAML double
quotes, escape sequences are live — \t is a tab, \n is a newline — and
Windows paths are made of exactly those sequences:
- name: Create the release folder
ansible.windows.win_file:
path: "C:\temp\new_build" # \t → TAB, \n → newline
state: directory path: 'C:\temp\new_build' # nothing is an escape here
# or double every backslash: "C:\\temp\\new_build"The house rule: single-quote every Windows path and this bug class disappears. Double-escaping works but is easier to get half-right. Many Windows modules tolerate forward slashes, but mixing slash styles invites subtle comparison bugs. Pick backslashes-in-single-quotes and stay consistent.
Next lesson takes the bypass property to its most famous destination: a domain playbook touches a file share and Windows answers “Access is denied” — with perfectly good credentials.
at work, this sounds like
- “Wrap it in become — that gets around the WinRM restrictions.”
- Run the task under a runas logon so WUA, DPAPI and other non-interactive blocks stop failing it.
- “Does the service account have SeDebugPrivilege?”
- The account Ansible connects as needs that privilege for runas — members of Administrators carry it by default.
self-check — recall, not a test
1 A Windows Update task fails over WinRM, but the same install works fine when you RDP in. What is the Ansible-side fix?
2 Why is path: "C:\temp\new_build" broken, and what are the two fixes?
3 What does runas do about UAC — which token does it ask for?
lab (optional — never required)
Run win_shell whoami /all against your Windows target twice — with and without become — and compare the logon, group memberships and privilege list.
needs: A Windows VM reachable over WinRM — the target you set up in lesson 32.