Scripting and Automation 
GFI MAX RemoteManagement 
Mark Petrie, Director of Engineering 
GFI MAX
Scripting and Automation 
» Introduction to scripting in GFI MAX RemoteManagement: 
» Just what EXACTLY do we mean by scripting? 
» Who is using scripting and for what purpose? 
» Using built-in scripts 
» Pro-active Monitoring Checks 
» Automated Maintenance Tasks 
» Using community scripts from fixitscripts.com 
» Find solutions to problems you have 
» Writing your own scripts… 
» Return codes 
» Considerations 
» Getting started 
» Coding guidelines 
» Using the API 
» Examples
Introduction
Just what EXACTLY do we mean by scripting? 
» Upload, deploy, schedule and run scripts for additional: 
» Monitoring Checks (Windows, OSX and Linux) 
» Maintenance Tasks (Windows only) 
» Scripts can be written in variety of common languages: 
» DOS Batch and CMD 
» VBS and Powershell 
» Ruby, Python, Perl and PHP 
» Javascript 
» AppleScript 
» BASH 
» Upload script once, downloaded as required (without Agent update) 
» Very powerful, but also secure: 
» Script source can only be uploaded by superuser 
» Signed (public/private key encryption) when downloaded by Agents
Are people using it? 
» 7.5 million script checks run every day! 
» Over 140,000 monitoring script checks 
» 260,000 maintenance tasks run every day! 
» What is it being used for? 
» Monitoring bespoke applications and hardware 
» Automating onboarding new clients 
• Automating software installation 
• Enforcing standard configurations 
» Regular scheduled maintenance 
» Automated fault resolution
Using built-in scripts
Pro-active Monitoring Checks 
» Deploy as either 24x7 or DSC script check 
» Get alerts and view results in Dashboard and Client Reports 
» Timeout limited to 150 seconds
What Monitoring Checks are already available? 
» Application Control: 
» Running Process 
» System User Count 
» SQL Query 
» Exchange: 
» Large Mailboxes 
» Mail Queue Size 
» Store Control 
» Security Center: 
» Antivirus Status 
» Windows Firewall 
» Windows Update
What Monitoring Checks are already available? 
» Virtualisation: 
» VMware ESXi – Datastore Free Space 
» VMware ESXi Health – CPUs 
» VMware ESXi Health – Fans 
» VMware ESXi Health – Memory 
» VMware ESXi Health – PSUs 
» VMware ESXi Health – Sensors 
» VMware ESXi Health – Storage 
» VMware ESXi – Virtual Machine Inventory 
» VMware ESXi – Virtual Machine Power State
Monitoring Datastore Free Space and Storage Health
Monitoring running VMs
Monitoring VM resource usage
Automated Maintenance Tasks 
» Upload script to Dashboard 
» Deploy site wide or to individual workstations and servers 
» Schedule once per day, week or month 
» Run in response to a failed check 
» View results in Dashboard 
» Automated Tasks Report 
» Timeout per schedule
What Maintenance Tasks are already available? 
» Antivirus: 
» Malwarebytes 
» Sophos Definition Update 
» Application Control: 
» Running Process 
» SQL Query 
» Exchange: 
» Store Control 
» Clean-Up: 
» Clean Temp Files 
» Clear Event Log 
» Defrag 
» Windows 
» Schedule Reboot 
» Service Control 
» Virtualisation 
» VMware ESXi – Virtual Machine Control
Stopping, starting and restarting VMs
Using community scripts
fixitscripts.com 
433 problems / 
requests for scripts 
584 total scripts 
269 scripts tagged 
for MAX RM 
328 PowerShell 
scripts 
Visitors from over 
100 countries 
179 VBScript scripts 
18,420 visitors in 
last 3 months 
797 registered users 
Over 2 minutes 
duration per visit
Using script from fixitscripts.com
Writing your own scripts
Return codes 
» Extend GFI MAX to monitor anything!? 
» Use exit codes to cause check to fail: 
» Exit 0 to cause check to pass 
» Exit non-zero to cause check to fail 
» Exit >1000 to display text output in Dashboard 
» Batch 
echo “Error Message” 
exit 1001 
» VBS 
wscript.echo( “Error Message” ) 
wscript.Quit(1001) 
» PowerShell 
Write-Host “Error Message” 
Exit 1001
Considerations and Limitations
Local system account 
» User context (Session Zero) 
» No user interaction 
» No network Resources
Environment Variables 
» Command line arguments solve this…
Timeouts
Getting started
Documentation
Don’t reinvent the wheel! 
» Steal Learn from Others Scripts 
» fixitscripts.com 
» GFI Forum 
» LinkedIn 
» Google! 
» Identify the problem trying to solve 
» Look at ServiceDesk – where is time being spent on tickets 
» Check Google (Why reinvent the wheel?) 
» Investigate using tools (ProcessMonitor, ProcessExplorer, etc) 
» Find Applications/Commands 
» Command Switches 
» Use previous scripts as a template and import into GFI MAX
Example from LinkedIn (service recovery)
Example from LinkedIn (service recovery)
Script writing guidelines
Visual Basic and Powershell 
» Visual Basic Script fully supported since Windows 2000 
» Powershell supported from WindowsXP onwards 
» May need to be installed on some older systems 
» Using Windows Script Host WScript object, you can access: 
» Arguments passed to script 
» Command Line Shell 
» File System 
» Registry 
» Services 
» Network (not if running as Local System Account) 
» VBS can also access Windows Management Instrumentation
Script structure 
» Clearly identify problem trying solve 
» Any script needs to do the following: 
» Declare variables to be used 
» Parse command line arguments 
» Interact with Windows or Application 
» Handle any errors 
» Return results
Declaring variables and constants 
» Good practice to force all variables to be declared before use 
» Use g_ to indicate global variables and clarify variable scope 
» Use type hinting to indicate variables intended purpose 
» Use Constants for magic numbers that won’t change 
' Usage: { start | stop | restart } "Service Name“ 
Option Explicit 
Dim g_oArgs, g_nMode, g_sServiceName 
Const MODE_START = 101 
Const MODE_STOP = 102 
Const MODE_RESTART = 103
Command Line Arguments 
» Arguments passed into script via command line can be used to: 
» Control behaviour of script (for example: action to perform) 
» Pass in the target of script (for example: service to restart) 
» Setup additional environment variables (If not available to Local System) 
» Advantages over hard-coding script behaviour and target? 
» Common code (e.g. connect to service manager) can be reused 
» Reduces number of scripts and improves maintainability of library
Command Line Arguments 
» Accessing arguments: 
» DOS Batch uses %1, %2 etc (note %0 is name of script) 
» Linux shell scripts (BASH) use $1, $2 etc ($0 is name of script) 
» Dynamic langauges (Perl, PHP) use $argc (count) and @argv (array) 
» VBS uses WScript.Arguments object: 
• WScript.Arguments.Count method gives number of arguments 
• WScript.Arguments(0) is first argument etc 
» Scripts ran by Advanced Monitoring Agent: 
» Two arguments are always appended to command line (for debug) 
» -logfile logname can be ignored
Command Line Arguments 
' Usage: { start | stop | restart } "Service Name“ 
Set g_oArgs = WScript.Arguments 
If g_oArgs.Count < 2 Then 
WScript.Echo "Invalid Arguments" 
WScript.Quit(1) 
End If 
Select Case g_oArgs(0) 
Case "start" 
g_nMode = MODE_START 
Case "stop" 
g_nMode = MODE_STOP 
Case "restart" 
g_nMode = MODE_RESTART 
Case Else 
WScript.Echo "Invalid Args" 
WScript.Quit(1) 
End Select 
g_sServiceName = g_oArgs(1)
Interacting with applications 
» Windows Script Host can run applications on local system 
» Application has status 0 until it terminates 
Set g_oShell = WScript.CreateObject("WScript.Shell") 
Set g_oRunningApp = g_oShell.Exec( "c:/path/to/my.exe arg0 arg1" ) 
Do While g_oRunningApp.Status = 0 
WScript.Sleep 100 
Loop 
WScript.Echo "Application Terminated“ 
» Application will be ran as user Agent running under (Local System Acc) 
» Any pop-up or user intervention will likely cause script timeout
Interacting with file system 
• Create a File System Object to access any file or directory listing 
Set g_oFileSystem = CreateObject( "Scripting.FileSystemObject" ) 
Set g_oTextFile = g_oFileSystem.OpenTextFile( "c:test.txt", 1 ) 
Do Until g_oTextFile.AtEndOfStream 
g_sNextLine = g_oTextFile.Readline 
WScript.Echo g_sNextLine 
Loop 
• Use regular expressions to parse file contents 
Set oRegExp = New RegExp 
oRegExp.Pattern = "^GETd.pdf$" 
Do Until oTextFile.AtEndOfStream 
sCurrentLine = oTextFile.Readline 
If oRegExp.Test( sCurrentLine ) Then 
nAccessed = nAccessed + 1 
End If 
Loop 
• Regular expressions can also be used to extract or replace matches
Interacting with registry 
» Registry stores config and management information of OS and Apps 
» Hierarchical organisation of keys and values (like filesystem) 
» A key can store many other keys. 
» A key can have default data. 
» A value can only store data and cannot store other values or keys 
» Data types of values must be explicitly set on creation 
» REG_BINARY – Binary Data (0’s and 1’s) 
» REG_DWORD – Double Word (Numeric, up to 32bit values) 
» REG_QWORD – Quadruple Word (Numeric, up to 64bit values) 
» REG_MULTI_SZ – A Set of Strings 
» Retrieve a value from Registry using RegRead (e.g. path to application) 
Set g_oShell = WScript.CreateObject ("WScript.Shell") 
g_sMBAMLocation = g_oShell.RegRead _ 
("HKLMSOFTWAREMicrosoftWindowsCurrentVersionApp Pathsmbam.exe") 
» Write a value to registry using RegWrite (e.g. reconfigure an application) 
g_oShell.RegWrite ( “key_location”, “value”, “key_type” )
Handling errors 
» On Error GoTo 0 (default) 
» Will cause script to exit, use only for fatal non-recoverable errors 
» On Error Resume Next 
» Will cause script execution to continue, allowing you to handle error 
» Err variable set to last error code 
» Script follows rule until presented with another error handing instruction 
» The scope of rule is per sub-routine only 
» Use function to handle errors consistently 
Function stHandleFatalError( innExitCode, insMsg ) 
If Err.Number <> 0 Then 
Err.Clear 
On Error GoTo 0 
WScript.Echo insMsg 
Wscript.Quit innExitCode 
End If 
On Error Resume Next 
Err.Clear 
End Function
Return results to Dashboard 
» Use exit codes to cause check to fail: 
» Exit 0 to cause check to pass 
» Exit non-zero to cause check to fail 
» Exit >1000 to display text output in Dashboard 
» Batch 
echo “Error Message” 
exit 1001 
» VBS 
wscript.echo( “Error Message” ) 
wscript.Quit(1001) 
» PowerShell 
Write-Host “Error Message” 
Exit 1001
Putting it all together 
Option Explicit 
Dim g_oWindowsFirewall 
On Error Resume Next 
Set g_oWindowsFirewall = WScript.CreateObject( "HNetCfg.FwMgr" ) 
stHandleFatalError 2001, "Unable to create Firewall object" 
If g_oWindowsFirewall.LocalPolicy.CurrentProfile.FirewallEnabled = 1 Then 
WScript.Echo "Windows Firewall Enabled" 
WScript.Quit ( 0 ) 
Else 
WScript.Echo "Windows Firewall Disabled" 
WScript.Quit ( 2000 ) 
End If 
Function stHandleFatalError( innExitCode, insMsg ) 
If Err.Number <> 0 Then 
Err.Clear 
On Error GoTo 0 
WScript.Echo insMsg 
Wscript.Quit innExitCode 
End If 
On Error Resume Next 
Err.Clear 
End Function
Windows Management Instrumentation 
» WMI allows access to almost all Windows components 
» Make modifications to settings and initiate operations 
» For example, check Print Spooler is running… 
sServiceName = "Spooler" 
sComputer = "." 
On Error Resume Next 
Set oWMIService = GetObject("winmgmts:" & strComputer & "rootCIMV2") 
stHandleFatalError( ERROR_CREATEOBJECT_WMI ) 
Set oService = oWMIService.Get("Win32_Service.Name='" & sServiceName & "'") 
If oService.State = "Running" Then 
WScript.Echo "Print Spooler is Running" 
WScript.Quit ( 0 ) 
Else 
' Restart Service etc...
Windows Management Instrumentation 
http://msdn.microsoft.com/en-us/library/aa394554(v=vs.85).aspx
Scripting and API
Getting the data you need from API 
» Used mainly to get data out of GFI MAX RemoteManagement 
» Easy to manipulate with PowerShell: 
$apikey = “YOUR API KEY" 
$clientsurl = "https://www.systemmonitor.us/api/?apikey=$apikey&service=list_clients" 
[xml]$xmlclients = (new-object System.Net.WebClient).DownloadString($clientsurl) 
» Example Uses: 
» Getting serial number data 
» Getting MAC addresses for Wake-on-LAN 
» See online help system for full instructions
Example: Workstations that have not been scanned in 90 days 
$apikey = "YOUR API KEY" 
$CurrDate = Get-Date 
$clientsurl = "https://www.systemmonitor.us/api/?apikey=$apikey&service=list_clients" 
$wstable = @() 
[xml]$xmlclients = (new-object System.Net.WebClient).DownloadString($clientsurl) 
foreach ($xmlclientslist in $xmlclients.result.items.client) { 
$clientid = $xmlclientslist.clientid 
$sitesurl="https://www.systemmonitor.us/api/? 
apikey=$apikey&service=list_sites&clientid=$clientid" 
[xml]$xmlsites = (new-object System.Net.WebClient).DownloadString($sitesurl) 
foreach ($xmlsiteslist in $xmlsites.result.items.site) { 
$siteid = $xmlsiteslist.siteid 
$wsurl = "https://www.hound-dog.us/api/? 
apikey=$apikey&service=list_workstations&siteid=$siteid" 
[xml]$xmlws = (new-object System.Net.WebClient).DownloadString($wsurl) 
foreach ($xmlwslist in $xmlws.result.items.workstation) { 
[datetime]$wsdate = $xmlwslist.last_scan_time 
if (($CurrDate).Subtract($wsdate).Days -gt 90) { 
$wsObj = "" | select Client,WSName,Age 
$wsObj.Client = $xmlclientslist.name."#cdata-section" 
$wsObj.WSName = $xmlwslist.name."#cdata-section" 
$wsObj.Age = ($CurrDate).Subtract($wsdate).Days 
$wstable += $wsObj 
}}}}
Example: Wake devices before patching 
param($siteid) 
$apikey = "Put your API Key here“ 
$apiurl = “https://www.systemmonitor.us/api/?apikey=$apikey” 
$url = "$($apiurl)&service=list_workstations&siteid=$siteid" 
[xml]$xmlmac = (new-object System.Net.WebClient).DownloadString($url) 
foreach ($xmlmacws in $xmlmac.result.items.workstation) { 
$macString = $xmlmacws.mac1."#cdata-section" 
$mac = $macString.split(':') | %{ [byte]('0x' + $_) } 
$UDPclient = new-Object System.Net.Sockets.UdpClient 
$UDPclient.Connect(([System.Net.IPAddress]::Broadcast),4000) 
$packet = [byte[]](,0xFF * 6) 
$packet += $mac * 16 
[void] $UDPclient.Send($packet, $packet.Length) 
write-output "Wake-On-Lan magic packet of length $($packet.Length) sent to 
$macString" 
}
Real-world examples
Real-world examples 
» Custom Monitoring 
» Automate repetitive tasks 
» Onboarding new clients 
» Software installation 
» Preventing tickets
Custom Monitoring 
» Check current time vs. NTP server 
$ntpcheck = w32tm /stripchart /dataonly /computer:pool.ntp.org /samples:1 
[int]$ntpchecktime = $($ntpcheck.Split()[-1]).Split("s")[0].Substring("1") 
Write-Output "$ntpchecktime seconds" 
if ($ntpchecktime -gt 300) { 
Write-Output "Check failed" 
Exit 1001 
}
Onboarding new clients 
» Make sure all of your standards are enforced from the start 
» Install and configure SNMP 
» Software deployment 
» Enable RDP 
» Enable Wake on LAN 
» Open ports in the firewall
Install and configure SNMP 
cmd /c Servermanagercmd -install SNMP-Services 
reg add HKEY_LOCAL_MACHINESYSTEMCurrentControlSet 
servicesSNMPParametersValidCommunities /v ROString /t 
REG_DWORD /d 4 /f 
reg delete HKEY_LOCAL_MACHINESYSTEMCurrentControlSet 
ServicesSNMPParametersPermittedManagers /f 
Stop-Service -Name SNMP 
Start-Service -Name SNMP
Software deployment 
» Download MSI or EXE and use silent switches to install software 
» Host on your website, Dropbox, or similar file storage solution 
» Silent switches are typically available with software documentation 
» MSI install files always use msiexec with the same switches for installation 
Msiexec /I {filepath} /quiet /qn /norestart REBOOT=reallysuppress 
» Check HKLMSoftwareMicrosoftWindowsUninstall for MSI uninstall string. Add /quiet to 
switch to make quiet 
Msiexec /I {filepath} /quiet /qn /norestart REBOOT=reallysuppress
Download and install OpenManage 
$file_url = "http://downloads-us.dell.com/FOLDER00574377M/1/OM-SrvAdmin-Dell- 
Web-WIN-7.1.0-5304_A00.exe" 
$file_name = "OMSA-6.5.0-2247_A01.exe" 
$numafiles_path = "$Env:SystemDriveNumaNetworks" 
if ((Test-Path $numafiles_path) -eq $false) { 
New-Item -type directory -Path $numafiles_path | Out-Null 
} 
if ((Test-Path "$numafiles_path$($file_name)") -eq $false) { 
$file_dload_file = "$numafiles_path$($file_name)" 
$file_dload = new-object System.Net.WebClient 
$file_dload.DownloadFile($file_url,$file_dload_file) 
cmd /c $numafiles_path$file_name /auto $numafiles_pathOpenManage 
} 
cmd /c msiexec /i 
$numafiles_pathOpenManageWindowsSystemsManagementSysMgmt.msi 
/quiet /norestart
Preventing tickets 
» Fix problems detected by your monitoring scripts 
» Reduce the amount of tickets coming into your helpdesk 
» Setup using an automated task 
» Don’t run at a specified time, run at a specified event 
» Able to run at the failure of most checks (Service, Event, AV Update) 
» Script will run at next 24/7 check-in following failure 
» Examples: 
» Clear and start print spooler when service stops 
» Force AV definition update when definitions are old 
» Run disk cleanups when disk gets full
Clear Print Spooler and restart service 
Set objShell = CreateObject("WScript.Shell") 
Set objFSO = CreateObject("Scripting.FileSystemObject") 
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!"_ 
& “.rootcimv2") 
SpoolDirectory = objShell.RegRead("HKLMSystemCurrentControlSet"_ 
& "ControlPrintPrintersDefaultSpoolDirectory") 
Set objFolder = objFSO.GetFolder(SpoolDirectory) 
For Each objFile In objFolder.Files 
WScript.Echo "Deleteing "+objFile.Name 
objFile.Delete(Force) 
Next 
Set objSpooler = objWMIService.Get("Win32_Service='spooler'") 
If objSpooler.State = "Stopped" Then 
WScript.Echo "Starting Spooler." 
objSpooler.StartService() 
End If
Summary
Summary 
» Scripting allows you to extend monitoring and automate maintenance 
» 7.5 million script checks and 260,000 maintenance tasks run every day 
» Built-in scripts available to add now with no programming knowledge required 
» Hundreds of community scripts available on fixitscripts.com for you to use 
» If you do want to write your own scripts 
» Ensure script returns appropriate return code for pass/fail 
» See script writing guidelines in help system 
» Borrow and build on top of other scripts 
» Save time onboarding new clients, automating maintenance and preventing tickets 
» Check your ServiceDesk for where time is being spent on tickets
Thank You 
Conferences.gfimax.com/app

Scripting and Automation within the MAX Platform - Mark Petrie

  • 1.
    Scripting and Automation GFI MAX RemoteManagement Mark Petrie, Director of Engineering GFI MAX
  • 2.
    Scripting and Automation » Introduction to scripting in GFI MAX RemoteManagement: » Just what EXACTLY do we mean by scripting? » Who is using scripting and for what purpose? » Using built-in scripts » Pro-active Monitoring Checks » Automated Maintenance Tasks » Using community scripts from fixitscripts.com » Find solutions to problems you have » Writing your own scripts… » Return codes » Considerations » Getting started » Coding guidelines » Using the API » Examples
  • 3.
  • 4.
    Just what EXACTLYdo we mean by scripting? » Upload, deploy, schedule and run scripts for additional: » Monitoring Checks (Windows, OSX and Linux) » Maintenance Tasks (Windows only) » Scripts can be written in variety of common languages: » DOS Batch and CMD » VBS and Powershell » Ruby, Python, Perl and PHP » Javascript » AppleScript » BASH » Upload script once, downloaded as required (without Agent update) » Very powerful, but also secure: » Script source can only be uploaded by superuser » Signed (public/private key encryption) when downloaded by Agents
  • 5.
    Are people usingit? » 7.5 million script checks run every day! » Over 140,000 monitoring script checks » 260,000 maintenance tasks run every day! » What is it being used for? » Monitoring bespoke applications and hardware » Automating onboarding new clients • Automating software installation • Enforcing standard configurations » Regular scheduled maintenance » Automated fault resolution
  • 6.
  • 7.
    Pro-active Monitoring Checks » Deploy as either 24x7 or DSC script check » Get alerts and view results in Dashboard and Client Reports » Timeout limited to 150 seconds
  • 8.
    What Monitoring Checksare already available? » Application Control: » Running Process » System User Count » SQL Query » Exchange: » Large Mailboxes » Mail Queue Size » Store Control » Security Center: » Antivirus Status » Windows Firewall » Windows Update
  • 9.
    What Monitoring Checksare already available? » Virtualisation: » VMware ESXi – Datastore Free Space » VMware ESXi Health – CPUs » VMware ESXi Health – Fans » VMware ESXi Health – Memory » VMware ESXi Health – PSUs » VMware ESXi Health – Sensors » VMware ESXi Health – Storage » VMware ESXi – Virtual Machine Inventory » VMware ESXi – Virtual Machine Power State
  • 10.
    Monitoring Datastore FreeSpace and Storage Health
  • 11.
  • 12.
  • 13.
    Automated Maintenance Tasks » Upload script to Dashboard » Deploy site wide or to individual workstations and servers » Schedule once per day, week or month » Run in response to a failed check » View results in Dashboard » Automated Tasks Report » Timeout per schedule
  • 14.
    What Maintenance Tasksare already available? » Antivirus: » Malwarebytes » Sophos Definition Update » Application Control: » Running Process » SQL Query » Exchange: » Store Control » Clean-Up: » Clean Temp Files » Clear Event Log » Defrag » Windows » Schedule Reboot » Service Control » Virtualisation » VMware ESXi – Virtual Machine Control
  • 15.
    Stopping, starting andrestarting VMs
  • 16.
  • 17.
    fixitscripts.com 433 problems/ requests for scripts 584 total scripts 269 scripts tagged for MAX RM 328 PowerShell scripts Visitors from over 100 countries 179 VBScript scripts 18,420 visitors in last 3 months 797 registered users Over 2 minutes duration per visit
  • 18.
    Using script fromfixitscripts.com
  • 19.
  • 20.
    Return codes »Extend GFI MAX to monitor anything!? » Use exit codes to cause check to fail: » Exit 0 to cause check to pass » Exit non-zero to cause check to fail » Exit >1000 to display text output in Dashboard » Batch echo “Error Message” exit 1001 » VBS wscript.echo( “Error Message” ) wscript.Quit(1001) » PowerShell Write-Host “Error Message” Exit 1001
  • 21.
  • 22.
    Local system account » User context (Session Zero) » No user interaction » No network Resources
  • 23.
    Environment Variables »Command line arguments solve this…
  • 24.
  • 25.
  • 26.
  • 27.
    Don’t reinvent thewheel! » Steal Learn from Others Scripts » fixitscripts.com » GFI Forum » LinkedIn » Google! » Identify the problem trying to solve » Look at ServiceDesk – where is time being spent on tickets » Check Google (Why reinvent the wheel?) » Investigate using tools (ProcessMonitor, ProcessExplorer, etc) » Find Applications/Commands » Command Switches » Use previous scripts as a template and import into GFI MAX
  • 28.
    Example from LinkedIn(service recovery)
  • 29.
    Example from LinkedIn(service recovery)
  • 30.
  • 31.
    Visual Basic andPowershell » Visual Basic Script fully supported since Windows 2000 » Powershell supported from WindowsXP onwards » May need to be installed on some older systems » Using Windows Script Host WScript object, you can access: » Arguments passed to script » Command Line Shell » File System » Registry » Services » Network (not if running as Local System Account) » VBS can also access Windows Management Instrumentation
  • 32.
    Script structure »Clearly identify problem trying solve » Any script needs to do the following: » Declare variables to be used » Parse command line arguments » Interact with Windows or Application » Handle any errors » Return results
  • 33.
    Declaring variables andconstants » Good practice to force all variables to be declared before use » Use g_ to indicate global variables and clarify variable scope » Use type hinting to indicate variables intended purpose » Use Constants for magic numbers that won’t change ' Usage: { start | stop | restart } "Service Name“ Option Explicit Dim g_oArgs, g_nMode, g_sServiceName Const MODE_START = 101 Const MODE_STOP = 102 Const MODE_RESTART = 103
  • 34.
    Command Line Arguments » Arguments passed into script via command line can be used to: » Control behaviour of script (for example: action to perform) » Pass in the target of script (for example: service to restart) » Setup additional environment variables (If not available to Local System) » Advantages over hard-coding script behaviour and target? » Common code (e.g. connect to service manager) can be reused » Reduces number of scripts and improves maintainability of library
  • 35.
    Command Line Arguments » Accessing arguments: » DOS Batch uses %1, %2 etc (note %0 is name of script) » Linux shell scripts (BASH) use $1, $2 etc ($0 is name of script) » Dynamic langauges (Perl, PHP) use $argc (count) and @argv (array) » VBS uses WScript.Arguments object: • WScript.Arguments.Count method gives number of arguments • WScript.Arguments(0) is first argument etc » Scripts ran by Advanced Monitoring Agent: » Two arguments are always appended to command line (for debug) » -logfile logname can be ignored
  • 36.
    Command Line Arguments ' Usage: { start | stop | restart } "Service Name“ Set g_oArgs = WScript.Arguments If g_oArgs.Count < 2 Then WScript.Echo "Invalid Arguments" WScript.Quit(1) End If Select Case g_oArgs(0) Case "start" g_nMode = MODE_START Case "stop" g_nMode = MODE_STOP Case "restart" g_nMode = MODE_RESTART Case Else WScript.Echo "Invalid Args" WScript.Quit(1) End Select g_sServiceName = g_oArgs(1)
  • 37.
    Interacting with applications » Windows Script Host can run applications on local system » Application has status 0 until it terminates Set g_oShell = WScript.CreateObject("WScript.Shell") Set g_oRunningApp = g_oShell.Exec( "c:/path/to/my.exe arg0 arg1" ) Do While g_oRunningApp.Status = 0 WScript.Sleep 100 Loop WScript.Echo "Application Terminated“ » Application will be ran as user Agent running under (Local System Acc) » Any pop-up or user intervention will likely cause script timeout
  • 38.
    Interacting with filesystem • Create a File System Object to access any file or directory listing Set g_oFileSystem = CreateObject( "Scripting.FileSystemObject" ) Set g_oTextFile = g_oFileSystem.OpenTextFile( "c:test.txt", 1 ) Do Until g_oTextFile.AtEndOfStream g_sNextLine = g_oTextFile.Readline WScript.Echo g_sNextLine Loop • Use regular expressions to parse file contents Set oRegExp = New RegExp oRegExp.Pattern = "^GETd.pdf$" Do Until oTextFile.AtEndOfStream sCurrentLine = oTextFile.Readline If oRegExp.Test( sCurrentLine ) Then nAccessed = nAccessed + 1 End If Loop • Regular expressions can also be used to extract or replace matches
  • 39.
    Interacting with registry » Registry stores config and management information of OS and Apps » Hierarchical organisation of keys and values (like filesystem) » A key can store many other keys. » A key can have default data. » A value can only store data and cannot store other values or keys » Data types of values must be explicitly set on creation » REG_BINARY – Binary Data (0’s and 1’s) » REG_DWORD – Double Word (Numeric, up to 32bit values) » REG_QWORD – Quadruple Word (Numeric, up to 64bit values) » REG_MULTI_SZ – A Set of Strings » Retrieve a value from Registry using RegRead (e.g. path to application) Set g_oShell = WScript.CreateObject ("WScript.Shell") g_sMBAMLocation = g_oShell.RegRead _ ("HKLMSOFTWAREMicrosoftWindowsCurrentVersionApp Pathsmbam.exe") » Write a value to registry using RegWrite (e.g. reconfigure an application) g_oShell.RegWrite ( “key_location”, “value”, “key_type” )
  • 40.
    Handling errors »On Error GoTo 0 (default) » Will cause script to exit, use only for fatal non-recoverable errors » On Error Resume Next » Will cause script execution to continue, allowing you to handle error » Err variable set to last error code » Script follows rule until presented with another error handing instruction » The scope of rule is per sub-routine only » Use function to handle errors consistently Function stHandleFatalError( innExitCode, insMsg ) If Err.Number <> 0 Then Err.Clear On Error GoTo 0 WScript.Echo insMsg Wscript.Quit innExitCode End If On Error Resume Next Err.Clear End Function
  • 41.
    Return results toDashboard » Use exit codes to cause check to fail: » Exit 0 to cause check to pass » Exit non-zero to cause check to fail » Exit >1000 to display text output in Dashboard » Batch echo “Error Message” exit 1001 » VBS wscript.echo( “Error Message” ) wscript.Quit(1001) » PowerShell Write-Host “Error Message” Exit 1001
  • 42.
    Putting it alltogether Option Explicit Dim g_oWindowsFirewall On Error Resume Next Set g_oWindowsFirewall = WScript.CreateObject( "HNetCfg.FwMgr" ) stHandleFatalError 2001, "Unable to create Firewall object" If g_oWindowsFirewall.LocalPolicy.CurrentProfile.FirewallEnabled = 1 Then WScript.Echo "Windows Firewall Enabled" WScript.Quit ( 0 ) Else WScript.Echo "Windows Firewall Disabled" WScript.Quit ( 2000 ) End If Function stHandleFatalError( innExitCode, insMsg ) If Err.Number <> 0 Then Err.Clear On Error GoTo 0 WScript.Echo insMsg Wscript.Quit innExitCode End If On Error Resume Next Err.Clear End Function
  • 43.
    Windows Management Instrumentation » WMI allows access to almost all Windows components » Make modifications to settings and initiate operations » For example, check Print Spooler is running… sServiceName = "Spooler" sComputer = "." On Error Resume Next Set oWMIService = GetObject("winmgmts:" & strComputer & "rootCIMV2") stHandleFatalError( ERROR_CREATEOBJECT_WMI ) Set oService = oWMIService.Get("Win32_Service.Name='" & sServiceName & "'") If oService.State = "Running" Then WScript.Echo "Print Spooler is Running" WScript.Quit ( 0 ) Else ' Restart Service etc...
  • 44.
    Windows Management Instrumentation http://msdn.microsoft.com/en-us/library/aa394554(v=vs.85).aspx
  • 45.
  • 46.
    Getting the datayou need from API » Used mainly to get data out of GFI MAX RemoteManagement » Easy to manipulate with PowerShell: $apikey = “YOUR API KEY" $clientsurl = "https://www.systemmonitor.us/api/?apikey=$apikey&service=list_clients" [xml]$xmlclients = (new-object System.Net.WebClient).DownloadString($clientsurl) » Example Uses: » Getting serial number data » Getting MAC addresses for Wake-on-LAN » See online help system for full instructions
  • 47.
    Example: Workstations thathave not been scanned in 90 days $apikey = "YOUR API KEY" $CurrDate = Get-Date $clientsurl = "https://www.systemmonitor.us/api/?apikey=$apikey&service=list_clients" $wstable = @() [xml]$xmlclients = (new-object System.Net.WebClient).DownloadString($clientsurl) foreach ($xmlclientslist in $xmlclients.result.items.client) { $clientid = $xmlclientslist.clientid $sitesurl="https://www.systemmonitor.us/api/? apikey=$apikey&service=list_sites&clientid=$clientid" [xml]$xmlsites = (new-object System.Net.WebClient).DownloadString($sitesurl) foreach ($xmlsiteslist in $xmlsites.result.items.site) { $siteid = $xmlsiteslist.siteid $wsurl = "https://www.hound-dog.us/api/? apikey=$apikey&service=list_workstations&siteid=$siteid" [xml]$xmlws = (new-object System.Net.WebClient).DownloadString($wsurl) foreach ($xmlwslist in $xmlws.result.items.workstation) { [datetime]$wsdate = $xmlwslist.last_scan_time if (($CurrDate).Subtract($wsdate).Days -gt 90) { $wsObj = "" | select Client,WSName,Age $wsObj.Client = $xmlclientslist.name."#cdata-section" $wsObj.WSName = $xmlwslist.name."#cdata-section" $wsObj.Age = ($CurrDate).Subtract($wsdate).Days $wstable += $wsObj }}}}
  • 48.
    Example: Wake devicesbefore patching param($siteid) $apikey = "Put your API Key here“ $apiurl = “https://www.systemmonitor.us/api/?apikey=$apikey” $url = "$($apiurl)&service=list_workstations&siteid=$siteid" [xml]$xmlmac = (new-object System.Net.WebClient).DownloadString($url) foreach ($xmlmacws in $xmlmac.result.items.workstation) { $macString = $xmlmacws.mac1."#cdata-section" $mac = $macString.split(':') | %{ [byte]('0x' + $_) } $UDPclient = new-Object System.Net.Sockets.UdpClient $UDPclient.Connect(([System.Net.IPAddress]::Broadcast),4000) $packet = [byte[]](,0xFF * 6) $packet += $mac * 16 [void] $UDPclient.Send($packet, $packet.Length) write-output "Wake-On-Lan magic packet of length $($packet.Length) sent to $macString" }
  • 49.
  • 50.
    Real-world examples »Custom Monitoring » Automate repetitive tasks » Onboarding new clients » Software installation » Preventing tickets
  • 51.
    Custom Monitoring »Check current time vs. NTP server $ntpcheck = w32tm /stripchart /dataonly /computer:pool.ntp.org /samples:1 [int]$ntpchecktime = $($ntpcheck.Split()[-1]).Split("s")[0].Substring("1") Write-Output "$ntpchecktime seconds" if ($ntpchecktime -gt 300) { Write-Output "Check failed" Exit 1001 }
  • 52.
    Onboarding new clients » Make sure all of your standards are enforced from the start » Install and configure SNMP » Software deployment » Enable RDP » Enable Wake on LAN » Open ports in the firewall
  • 53.
    Install and configureSNMP cmd /c Servermanagercmd -install SNMP-Services reg add HKEY_LOCAL_MACHINESYSTEMCurrentControlSet servicesSNMPParametersValidCommunities /v ROString /t REG_DWORD /d 4 /f reg delete HKEY_LOCAL_MACHINESYSTEMCurrentControlSet ServicesSNMPParametersPermittedManagers /f Stop-Service -Name SNMP Start-Service -Name SNMP
  • 54.
    Software deployment »Download MSI or EXE and use silent switches to install software » Host on your website, Dropbox, or similar file storage solution » Silent switches are typically available with software documentation » MSI install files always use msiexec with the same switches for installation Msiexec /I {filepath} /quiet /qn /norestart REBOOT=reallysuppress » Check HKLMSoftwareMicrosoftWindowsUninstall for MSI uninstall string. Add /quiet to switch to make quiet Msiexec /I {filepath} /quiet /qn /norestart REBOOT=reallysuppress
  • 55.
    Download and installOpenManage $file_url = "http://downloads-us.dell.com/FOLDER00574377M/1/OM-SrvAdmin-Dell- Web-WIN-7.1.0-5304_A00.exe" $file_name = "OMSA-6.5.0-2247_A01.exe" $numafiles_path = "$Env:SystemDriveNumaNetworks" if ((Test-Path $numafiles_path) -eq $false) { New-Item -type directory -Path $numafiles_path | Out-Null } if ((Test-Path "$numafiles_path$($file_name)") -eq $false) { $file_dload_file = "$numafiles_path$($file_name)" $file_dload = new-object System.Net.WebClient $file_dload.DownloadFile($file_url,$file_dload_file) cmd /c $numafiles_path$file_name /auto $numafiles_pathOpenManage } cmd /c msiexec /i $numafiles_pathOpenManageWindowsSystemsManagementSysMgmt.msi /quiet /norestart
  • 56.
    Preventing tickets »Fix problems detected by your monitoring scripts » Reduce the amount of tickets coming into your helpdesk » Setup using an automated task » Don’t run at a specified time, run at a specified event » Able to run at the failure of most checks (Service, Event, AV Update) » Script will run at next 24/7 check-in following failure » Examples: » Clear and start print spooler when service stops » Force AV definition update when definitions are old » Run disk cleanups when disk gets full
  • 57.
    Clear Print Spoolerand restart service Set objShell = CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!"_ & “.rootcimv2") SpoolDirectory = objShell.RegRead("HKLMSystemCurrentControlSet"_ & "ControlPrintPrintersDefaultSpoolDirectory") Set objFolder = objFSO.GetFolder(SpoolDirectory) For Each objFile In objFolder.Files WScript.Echo "Deleteing "+objFile.Name objFile.Delete(Force) Next Set objSpooler = objWMIService.Get("Win32_Service='spooler'") If objSpooler.State = "Stopped" Then WScript.Echo "Starting Spooler." objSpooler.StartService() End If
  • 58.
  • 59.
    Summary » Scriptingallows you to extend monitoring and automate maintenance » 7.5 million script checks and 260,000 maintenance tasks run every day » Built-in scripts available to add now with no programming knowledge required » Hundreds of community scripts available on fixitscripts.com for you to use » If you do want to write your own scripts » Ensure script returns appropriate return code for pass/fail » See script writing guidelines in help system » Borrow and build on top of other scripts » Save time onboarding new clients, automating maintenance and preventing tickets » Check your ServiceDesk for where time is being spent on tickets
  • 60.