How to login to Windows and Run command from Linux

How to login to Windows and Run command from Linux

Introduction –
In many cloud application you need to login to Windows from Linux server and run Windows native command or Powershell command to perform certain task.
There are two options to do this.

1) Winexe (outdated)-
NOTE – You can use it if it works for you!
Winexe remotely executes commands on Windows NT/2000/XP/2003 systems from GNU/Linux

    eg - winexe --user='<USERNAME>' //<HOSTNAME or IPADDRESS> "ipconfig /all"

2) Ruby or Python and WinRM –

* What is Windows Remote Management (WinRM)?
Windows Remote Management (WinRM) is the Microsoft implementation of WS-Management Protocol, a standard Simple Object Access Protocol (SOAP)-based, firewall-friendly protocol that    allows hardware and operating systems, from different vendors, to interoperate. Refere https://msdn.microsoft.com/en-us/library/aa384426.aspx for more information.

* What is PowerShell Remoting Protocol?
PowerShell Remoting allows me to run commands on a remote system as if I was sitting in front of it. It provides a consistent framework for managing computers across a network.
Windows PowerShell Remoting Protocol, which encodes messages prior to sending them over the Web Services Management Protocol Extensions for the Windows.

NOTE- “Enable-PSRemoting” service should be running on Windows server. (Command: Enable-PSRemoting -Force)

* WinRM and the Python library pywinrm (https://github.com/diyan/pywinrm)
   * WinRM and the Ruby library winrm

In this blog, we will use Ruby winrm library and see how we can monitor Windows service. Please find installation steps.

# yum install ruby-devel
# gem install -r winrm

Scripts-

#!/usr/bin/env /usr/bin/ruby

require 'rubygems'
require 'fileutils'
require 'highline/import'
require 'optparse'
require 'winrm'

############
options = {}
args = OptionParser.new do |opts|
  opts.on('-h', '--help', 'Show help') do
     puts opts
     exit
  end

  opts.on('-', /\A-\Z/) do
    puts opts
    exit(1)
  end

  opts.on('-H', '--hostname HOSTNAME', 'Hostname') do |hostname|
    options[:hostname] = hostname
  end

  opts.on('-u', '--username USERNAME', 'Username') do |username|
    options[:username] = username
  end

  opts.on('-s', '--service SERVICE', 'Window Service') do |winsrv|
    options[:winsrv] = winsrv
  end

  opts.on('-f', '--passfile FILE', 'File with Password') do |v|
    options[:passfile] = v
  end
end
args.parse!
args.banner = "\nUsage: #{$PROGRAM_NAME} <options>\n\n"
#puts options

if !options[:hostname].nil? && !options[:username].nil? && !options[:winsrv].nil?
   my_service = options[:winsrv].to_s
   my_user = options[:username].to_s
   my_pass = nil
   if File.exist?(options[:passfile].to_s)
     windata = File.read(options[:passfile].to_s)
     my_pass = windata.chomp.strip
   else
     print 'Enter Password: '
     pass = ask('Password: ') { |q| q.echo = '*' }
     my_pass = pass.chomp
   end

   ## windows code ##
   win_host = File.join('http://', options[:hostname], ':5985/wsman')
   opts = {
     endpoint: win_host.to_s, user: my_user.to_s, password: my_pass.to_s
   }
   conn = WinRM::Connection.new(opts)

   # powershell
   # ps_cmd = "Get-WMIObject Win32_Service -filter \"name = '#{my_service}'\" "
   #shell = conn.shell(:powershell)
   #output = shell.run(ps_cmd)
   ##puts output.stdout.chomp
   #data = output.stdout.gsub(/\s+|\n+/, ' ')
   #data = data.gsub(/\s+:/, ':')
   #if ( data =~ /ExitCode\s+:\s+0/ ) || ( data =~ /ExitCode:\s+0/ )
   # puts "OK - #{data}"
   # exit 0
   #else
   # puts "CRITICAL - #{data}"
   # exit 2
   #end

  # normal shell
   my_cmd = "sc query #{my_service}"
   shell_cmd = conn.shell(:cmd)
   output1 = shell_cmd.run(my_cmd)
   data1 = output1.to_s.chomp
   data1 = output1.stdout.gsub(/\s+|\n+/, ' ')
   data1 = data1.gsub(/\s+:/, ':')
   #puts data1
   if ( data1 =~ /.*STATE\s+:.*RUNNING/ ) || ( data1 =~ /.*STATE:.*RUNNING/ )
     puts "OK - #{data1}"
     exit 0
   else
     puts "CRITICAL - #{data1}"
     exit 2
   end
else
 STDERR.puts args.banner
 STDERR.puts args.summarize
 exit(1)
end

#eof

* How to user Script

root@localhost# ./winservice-monitoring.rb -u ‘XXXXX’ -H <MYHOST> -f /tmp/password.txt  -s xagt
OK – SERVICE_NAME: xagt TYPE: 10 WIN32_OWN_PROCESS STATE: 4 RUNNING (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN) WIN32_EXIT_CODE: 0 (0x0) SERVICE_EXIT_CODE: 0 (0x0) CHECKPOINT: 0x0 WAIT_HINT: 0x0
root@localhost #

root@localhost # ./winservice-monitoring.rb -u ‘XXXXX’ -H <MYHOST> -f /tmp/password.txt  -s xxx
CRITICAL – [SC] EnumQueryServicesStatus:OpenService FAILED 1060: The specified service does not exist as an installed service.
root@localhost #

Reference:
https://github.com/WinRb/WinRM
https://sourceforge.net/projects/winexe
http://blogs.msdn.com/PowerShell

Thank you,
Arun Bagul

Similar Posts:

Be Sociable, Share!

Leave a Reply

Your email address will not be published. Required fields are marked *