ManageIQ leverages the WinRM gem to execute commands and
Powershell scripts on remote Windows systems from the local ManageIQ appliance.
Below is some guidance on how to configure and use WinRM within Automate.
- Make sure the WinRM service has been configured correctly on the remote Windows server. This is well documented online but I found the following link particularly concise and useful:
http://msdn.microsoft.com/en-us/library/aa384372(v=vs.85).aspx
The following error might be thrown when trying to connect to the WinRM service for the first time:
WinRM::WinRMHTTPTransportError: Bad HTTP response returned from server (401)..
Run the following commands locally on the Windows server in an elevated cmd prompt to try to solve the problem:
winrm set winrm/config/client/auth @{Basic="true"}
winrm set winrm/config/service/auth @{Basic="true"}
winrm set winrm/config/service @{AllowUnencrypted="true"}
-
The execution policy on a Windows server determines which Powershell scripts (if any) will be allowed to run. Make sure an appropriate policy is set. See http://technet.microsoft.com/en-us/library/ee176961.aspx for more details.
-
Below is a sample script that illustrates how to use the WinRM gem within Automate.
require 'json'
require 'winrm'
PS_SCRIPT = <<-PS_SCRIPT
$result = @{
"date" = Get-Date;
"services" = Get-Service
}
$result | ConvertTo-JSON
PS_SCRIPT
url_params = {
:ipaddress => "<hostname_or_ip>",
:port => 5985 # Default port 5985
}
connect_params = {
:user => "<username>", # Example: domain\\user
:pass => "<password>",
:disable_sspi => true
}
url = "http://#{url_params[:ipaddress]}:#{url_params[:port]}/wsman"
$evm.log("info", "Connecting to WinRM on URL :#{url}")
winrm = WinRM::WinRMWebService.new(url, :ssl, connect_params)
results = winrm.run_powershell_script(PS_SCRIPT)
# results is a hash with 2 keys:
# 1) The first key :data is an array with two hashes
# :stderr
# :stdout
# 2) the second key is the :exitcode.
errors = results[:data].collect { |d| d[:stderr] }.join
$evm.log("error", "WinRM returned stderr: #{errors}") unless errors.blank?
data = results[:data].collect { |d| d[:stdout] }.join
json_hash = JSON.parse(data, :symbolize_names => true)
$evm.log("info", "WinRM returned hash: #{json_hash.inspect}")