#!powershell # Copyright: (c) 2017, Dag Wieers (@dagwieers) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) #Requires -Module Ansible.ModuleUtils.Legacy #Requires -Module Ansible.ModuleUtils.ArgvParser #Requires -Module Ansible.ModuleUtils.CommandUtil # See also: https://technet.microsoft.com/en-us/sysinternals/pxexec.aspx $params = Parse-Args $args $command = Get-AnsibleParam -obj $params -name "command" -type "str" -failifempty $true $executable = Get-AnsibleParam -obj $params -name "executable" -type "path" -default "psexec.exe" $hostnames = Get-AnsibleParam -obj $params -name "hostnames" -type "list" $username = Get-AnsibleParam -obj $params -name "username" -type "str" $password = Get-AnsibleParam -obj $params -name "password" -type "str" $chdir = Get-AnsibleParam -obj $params -name "chdir" -type "path" $wait = Get-AnsibleParam -obj $params -name "wait" -type "bool" -default $true $nobanner = Get-AnsibleParam -obj $params -name "nobanner" -type "bool" -default $false $noprofile = Get-AnsibleParam -obj $params -name "noprofile" -type "bool" -default $false $elevated = Get-AnsibleParam -obj $params -name "elevated" -type "bool" -default $false $limited = Get-AnsibleParam -obj $params -name "limited" -type "bool" -default $false $system = Get-AnsibleParam -obj $params -name "system" -type "bool" -default $false $interactive = Get-AnsibleParam -obj $params -name "interactive" -type "bool" -default $false $session = Get-AnsibleParam -obj $params -name "session" -type "int" $priority = Get-AnsibleParam -obj $params -name "priority" -type "str" -validateset "background","low","belownormal","abovenormal","high","realtime" $timeout = Get-AnsibleParam -obj $params -name "timeout" -type "int" $extra_opts = Get-AnsibleParam -obj $params -name "extra_opts" -type "list" $result = @{ changed = $true } If (-Not (Get-Command $executable -ErrorAction SilentlyContinue)) { Fail-Json $result "Executable '$executable' was not found." } $arguments = [System.Collections.Generic.List`1[String]]@($executable) If ($nobanner -eq $true) { $arguments.Add("-nobanner") } # Support running on local system if no hostname is specified If ($hostnames) { $hostname_argument = ($hostnames | sort -Unique) -join ',' $arguments.Add("\\$hostname_argument") } # Username is optional If ($null -ne $username) { $arguments.Add("-u") $arguments.Add($username) } # Password is optional If ($null -ne $password) { $arguments.Add("-p") $arguments.Add($password) } If ($null -ne $chdir) { $arguments.Add("-w") $arguments.Add($chdir) } If ($wait -eq $false) { $arguments.Add("-d") } If ($noprofile -eq $true) { $arguments.Add("-e") } If ($elevated -eq $true) { $arguments.Add("-h") } If ($system -eq $true) { $arguments.Add("-s") } If ($interactive -eq $true) { $arguments.Add("-i") If ($null -ne $session) { $arguments.Add($session) } } If ($limited -eq $true) { $arguments.Add("-l") } If ($null -ne $priority) { $arguments.Add("-$priority") } If ($null -ne $timeout) { $arguments.Add("-n") $arguments.Add($timeout) } # Add additional advanced options If ($extra_opts) { ForEach ($opt in $extra_opts) { $arguments.Add($opt) } } $arguments.Add("-accepteula") $argument_string = Argv-ToString -arguments $arguments # add the command at the end of the argument string, we don't want to escape # that as psexec doesn't expect it to be one arg $argument_string += " $command" $start_datetime = [DateTime]::UtcNow $result.psexec_command = $argument_string $command_result = Run-Command -command $argument_string $end_datetime = [DateTime]::UtcNow $result.stdout = $command_result.stdout $result.stderr = $command_result.stderr If ($wait -eq $true) { $result.rc = $command_result.rc } else { $result.rc = 0 $result.pid = $command_result.rc } $result.start = $start_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") $result.end = $end_datetime.ToString("yyyy-MM-dd hh:mm:ss.ffffff") $result.delta = $($end_datetime - $start_datetime).ToString("h\:mm\:ss\.ffffff") Exit-Json $result