lodctr /R
Rebuild PerfMon Counters
OPSView and adding hosts through REST API
This is something I’ve decided to share after a couple of days tinkering with the REST API and wanting to automate adding of hosts.
My environment:
99.99% Windows based
My need:
Automate adding of new hosts as they are deployed on the network.
My plan:
Leverage PowerShell
Leverage WSUS
Leverage the OPSView REST API
My Skills:
I am in no way share or form a developer or someone who could tell you what JSON stands for or how it works. Just a plain old SYS Admin.
Prerequisites:
1. Version of OPSView that has the REST API. I’m using the latest Community Edition.
2. An OPSView contact/login that ha the correct permissions/roles to add new hosts and read data.
3. An OPSView top level host group you will use to host your auto added hosts.
4. A host to clone for your template that new hosts will look like.
5. You should already have WSUS
6. You should know how/what WSUS is.
7. You should know how to create custom WSUS packages and deploy them via WSUS. (Custom Update Publisher)
8. If not read up on them and decide if WSUS is something you want to be using in your org going forward and think about implementing it.
9. It’s simply my environment and thus it is what I want to be working with.
The Details:
So in essence what I want to do is a simple process every time a new Windows Server box is brought up on my domain.
1. Install OPSView agent.
2. Deploy custom .ini config file for agent and restart agent.
3. Add host to monitoring server into a predefined group so I know that this is a new server that needs further setup.
Steps 1 and 2 are easily accomplished with custom WSUS packages and rules to make sure the agent is only deployed when it needs to be and I’m not going to go into that at all. It’s pretty straight forward. If you’ve never done it before you should have the hang of Custom Packages within a day of playing around with it (on your test network of course). Those skills can then be used in the future for other Custom Packages.
This is about accessing the REST API through PowerShell which was something new to me.
I ended up with 2 different raw scripts. Many refinements could be made and I’m sure I’ll tweak them but as of right now these work for what I wanted them to do.
Script 1.
opsview-get-host-config.ps1
This script accesses the API to get the config of a host on the server. I use the output of this script to base my template for adding new hosts. I got the return data and then stripped out information like host ID (can’t duplicate that) and then I insert my own host name and IP when creating the new host later on. I inserted that data into the 2nd script.
Why use that as a template instead of building a host string completely dynamically in the script. This way is easier for me. Of course you can make the script more complex and thus more flexible but again this is a starting point for me (and maybe you) not a universal solution.
Script 2.
opsview-add-host.ps1
This script adds a host with the current IPv4 address and machine name it is running on to the placeholder group. Yes it’s that simple. But it works.
So a simple and useful solution for me. It could be more elegant but it does what I need it to. And once you have your prereqs set up you’d only be using script 2 for adding new hosts and since this can be automated via WSUS hosts will add themselves as your regulated patch cycles happen..
The 2 scripts are attached below.
Thanks for reading and for any comments.
##### opsview-get-host-config.ps1
##### Get OPSview Host Config
$urlauth = "http://opsview.host.org/rest/login"
#The host we will use to pull our data from
$urlconfigget = "http://opsview.host.org/rest/config/host/132"
$user="host-add-contact"
$pass="password"
$creds = '{"username":"' + $user + '","password":"' + $pass + '"}'
#Write-Host $creds
###Generate Auth Token
$bytes1 = [System.Text.Encoding]::ASCII.GetBytes($creds)
$web1 = [System.Net.WebRequest]::Create($urlauth)
$web1.Method = "POST"
$web1.ContentLength = $bytes1.Length
$web1.ContentType = "application/json"
$stream1 = $web1.GetRequestStream()
$stream1.Write($bytes1,0,$bytes1.Length)
$stream1.Close()
$reader1 = New-Object System.IO.Streamreader -ArgumentList $web1.GetResponse().GetResponseStream()
$token1 = $reader1.ReadToEnd()
$reader1.Close()
#Parse Token for follwoing sessions
#Write-Host $token1
$token1=$token1.Replace("{`"token`":`"", "")
$token1=$token1.Replace("`"}", "")
#Write-Host $token1
$web2 = [System.Net.WebRequest]::Create($urlconfigget)
$web2.Method = "GET"
$web2.ContentType = "application/json"
$web2.Headers.Add("X-Opsview-Username","$user")
$web2.Headers.Add("X-Opsview-Token",$token1);
$response2 = $web2.getResponse()
$reader2 = New-Object System.IO.Streamreader -ArgumentList $web2.GetResponse().GetResponseStream()
$result2 = $reader2.ReadToEnd()
Write-Host $result2
$reader2.Close()
##### opsview-add-host.ps1
##### Get OPSview Host Config
$urlauth = "http://opsview.host.org/rest/login"
$urlconfig = "http://opsview.host.org/rest/config/host"
$user="host-add-contact"
$pass="password"
$creds = '{"username":"' + $user + '","password":"' + $pass + '"}'
#Write-Host $creds
###Generate Auth Token
$bytes1 = [System.Text.Encoding]::ASCII.GetBytes($creds)
$web1 = [System.Net.WebRequest]::Create($urlauth)
$web1.Method = "POST"
$web1.ContentLength = $bytes1.Length
$web1.ContentType = "application/json"
$stream1 = $web1.GetRequestStream()
$stream1.Write($bytes1,0,$bytes1.Length)
$stream1.Close()
$reader1 = New-Object System.IO.Streamreader -ArgumentList $web1.GetResponse().GetResponseStream()
$token1 = $reader1.ReadToEnd()
$reader1.Close()
#Parse Token for follwoing sessions
$token1=$token1.Replace("{`"token`":`"", "")
$token1=$token1.Replace("`"}", "")
$hostname = $env:COMPUTERNAME
$hostip = ((ipconfig | findstr [0-9].\.)[0]).Split()[-1]
### The host data I use here is tailored to my OPSView setup. USe the other script and this line as a guide to building your own
$hostdata = '{"object":{"hosttemplates":[{"ref":"/rest/config/hosttemplate/42","name":"Connectivity - USA"},{"ref":"/rest/config/hosttemplate/36","name":"Server - All Windows Server Base Checks"}],"snmpv3_privprotocol":null,"flap_detection_enabled":"1","keywords":[],"check_period":{"ref":"/rest/config/timeperiod/1","name":"24x7"},"hostattributes":[],"notification_period":{"ref":"/rest/config/timeperiod/1","name":"24x7"},"notification_options":"d,r,f","tidy_ifdescr_level":"0","name":"' + $hostname +'","rancid_vendor":null,"snmp_community":"","hostgroup":{"ref":"/rest/config/hostgroup/42","name":"ZZZ-New Hosts"},"enable_snmp":"0","monitored_by":{"ref":"/rest/config/monitoringserver/1","name":"Master Monitoring Server"},"alias":"","parents":[],"uncommitted":"1","icon":{"name":"SYMBOL - Server","path":"/images/logos/server_small.png"},"retry_check_interval":"3","ip":"' + $hostip + '","use_mrtg":"0","snmp_max_msg_size":"0","servicechecks":[],"use_rancid":"0","snmp_version":"2c","snmpv3_authpassword":"","nmis_node_type":"router","use_nmis":"0","rancid_connection_type":"ssh","snmpv3_authprotocol":null,"rancid_username":null,"check_command":{"ref":"/rest/config/hostcheckcommand/15","name":"ping"},"rancid_password":null,"check_attempts":"5","check_interval":"15","notification_interval":"0","snmp_port":"161","snmpv3_username":"","snmpv3_privpassword":"","other_addresses":""}}'
$bytes2 = [System.Text.Encoding]::ASCII.GetBytes($hostdata)
$web2 = [System.Net.WebRequest]::Create($urlconfig)
$web2.Method = "POST"
$web2.ContentLength = $bytes2.Length
$web2.ContentType = "application/json"
$web2.Headers.Add("X-Opsview-Username","$user")
$web2.Headers.Add("X-Opsview-Token",$token1);
$stream2 = $web2.GetRequestStream()
$stream2.Write($bytes2,0,$bytes2.Length)
$stream2.Close()
$reader2 = New-Object System.IO.Streamreader -ArgumentList $web2.GetResponse().GetResponseStream()
$output2 = $reader2.ReadToEnd()
$reader2.Close()
Write-Host $output2
Using Robocopy
There are many switches and capabilities such as copying files with original timestamps, ntfs rights, differential copies, etc etc.
The common one I use when migrating shares from one location to another is for example. This retries, carries over NTFS premissions and does a differnetical copy so you can re run it later to sync the directories.
ROBOCOPY "\\server1\users$" "\\server2\users$" *.* /E /SEC /ZB /R:100000 /W:1 /TBD /XO
See here for more commands about RoboCopy.
http://ss64.com/nt/robocopy.html
Delete user from Sharepoint 2010 Cache
Warning: This will remove all unique profile information that user has entered.
To delete all data for a user from SharePoint 2010:
1. Go to Central Admin and delete profile if user has one in the User Profile Management section.
2. Go to http(s)://sitecollection.com/_catalogs/users find the offending user, click on it, and use the delete button.
This should also work for SharePoint 2007
Manually Remove Exchange 2003 Storage Groups/Public Folder
These checks are a good thing but sometimes things get screwed up and the checks will never pass so you manually must remove a Storage Group or Public Folders DB but the Exchange Management Console stops you due to these safety checks.
So here is the how to.
WARNING:
ADSI Edit is a very powerful tool and you can easily break all of your Exchange org if you do something stupid. Use this as a last resort to remove a Store or DB after taking care of things like replicas.
Drill down to where you need to to delete the offending Store/DB and then restart the MS Store service on the server. If doing this on a remote DC the changes might take several minutes to replicate.
Once again ADSI Edit can easily destroy your entire AD organization so please be careful and only do this if absolutely necessary.
Configuration
+ CN=Configuration
+ CN=Services
+ CN=Microsoft Exchange
+ CN=YOUR ORGANISATION
+ CN=Administrative Groups
+ CN=First Administrative Group
+ CN=Servers
+ CN=SERVER NAME
+ CN=InformationStore
Refresh Active Directory group memeberships WITHOUT rebooting
The standard way to fix this is to start a new session. With a user object this means a log off and log on; inelegant but not terrible. For a computer object there is no log on and off, the authentication happens when the computer authenticates against a domain controller and thus the fix is to restart the machine. This is not an option for production servers where uptime is critical.
So you've just deployed some new group policies based on some new group memberships you've created and you need those settings applied to production servers but a reboot is out of the question. The policy is not applying.
The solution without a reboot? Deleting existing tokens and forcing them to be recreated.
Open a cmd prompt and run the following two commands:
klist purge
klist tgt
This will delete the tokens and then recreate new ones. Your policy will now apply as expected and there was no reboot necessary!