In case you guys missed it, Lee Holmes had a ‘review’ copy of the upcoming PowerShell 2.0 Cookbook on the O’Reilly website for a bit. It has since been taken down in preparation for it’s August 15th release. It just so happens that when it was up it was under a Creative Commons license, which means I could distribute it. So I made a mirror on March 29th, and have now placed the book in its entirety online. Enjoy! You can also download it as a PDF if you’d prefer, with all links and such intact. If you like it, and I’m sure you will, then I highly encourage you to support Lee and buy a copy. And support me too and use my Amazon associate linked version. Or don’t support me, and use this link instead. Cheers!

 

People are doing a lot of interesting things with Powershell. Joel Bennett is a magician of “Look what it can do”. But then I came across this post from John Robbins’ blog and was blown away – Powerpoint, in Powershell. What better way to show the power and flexibility of Posh than to do it in posh! Friggin brilliant!

031010_2010_StartPowerS2[1]

 

Yesterday, posted quietly as KB article 968929, Microsoft officially released PowerShell 2.0

Why is that cool? Because now you can get PoSh 2 officially deployed to all your servers. And you get to “officially” use the coolest CmdLet in the bunch: New-WebServiceProxy

Now, if you were to just read the help about it, it doesn’t really seem all that interesting:

Creates a Web service proxy object that lets you use and manage the Web service in Windows PowerShell.

But I’m going to give you an awesome secret. There’s a webservice out there unlike any other. If you want to sell PoSh to your coworkers, this is the way to do it.

What is it?

WebServiceX_logo

WebServiceX.Net provides On Demand XML Web Services for Financial,Distribution, Retail, Health Care, Manufacturing, Telecom, Government and Educational Industry.

So, what’s the mean to us?

Well using our shiny new cmdLet and a few lines of code we can instantly access data for over 70 different services. So really it comes down to “What do you want to do?”

Get the weather? No problem.

1
2
$usWeather = New-WebServiceProxy uri http://www.webservicex.net/WeatherForecast.asmx?wsdl”
$usWeather.GetWeatherByZipCode(55408)

BAM. Done.

Oh, you don’t live in the US? No worries either.

Lets see how the weather of a certain favorite MS employee is.

1
2
3
$weather = New-WebServiceProxy uri "http://www.webservicex.net/globalweather.asmx?wsdl”
$weather.GetWeather(Amsterdam, Netherlands)

Amsterdamweather

Wow, Stefan better grab a coat, it’s chilly there.

Ok, those were interesting in an ‘yeah, I’ve seen that before’ way – but what else?

A simple-as-pie domain whois? You know it’s there.

1
2
3
$whois = New-WebServiceProxy uri http://www.webservicex.net/whois.asmx?wsdl”
$whois.GetWhois(Pavleck.Net)

PavleckNetWhois

BAM!

Next?

How about searching Lloyd’s for the risk code for a given item. Sure, we got it.

1
2
$lloyds = New-WebServiceProxy -uri "http://www.webservicex.net:85/LloydsRiskCodeService.asmx?wsdl"
$lloyds.GetLloydsRiskCodeDetailByRiskCodeDescription('OVERSEAS LEG TERRORISM PROPERTY')

LloydsRiskCode

BAM!

Apparently it’s risk code is 6T. No idea what that all means.

I could go on all day – there is so much information out there. From Acceleration Unit Converters, Sunset and Sunrise times, RSS Readers, Translation services, Barcode generation, Text to Braille – hell, it’ll even let you send Free SMS messages and Faxes to anyone!

As you can tell, it’s a pretty expansive list, with many options and a whole ton of data. Not always what you want when you’re trying to do a little Posh-Fu. So that’s why I’m working on a little script for you to dot source, one that “PoShifies” these various services and gives you a lot more options on the command line – look for that soon!

Oh, and before I forget – be sure to check out the PowerScripting Podcast tomorrow night because you’re in for a treat! Me, Marco Shaw, Marcus Oh and Scott Moss will be giving a little panel discussion about PowerShell in OpsMgr – the Command Shell as we’ve come to call it. So come listen in, ask some questions, and maybe win some sweet sweet schwag!

 

If you’re still hesitant to dive into powershell, you’re not alone. To someone who is a light scripter or has limited or no development background it can seem like a daunting task. A lot of the examples you’ll find are easy and simple, but Write-Host –Fore Green “Hello World! I’m using PowerShell” won’t help you with automating all of those tasks out there.

There are a few places to go, and a few books to read, to help you get up to speed with it.
One of the most promising looking resources would have to be Doug Finke’s “Try PowerShell”.

TryPowerShell

Try PowerShell  is an interactive PowerShell tutorial created with PowerShell using WPF (( Wikipedia: Windows Presentation Foundation )) and PowerBoots.
With it you can easily try out PowerShell commands just by clicking on them, no typing needed. You can search for particular commands, run them, and even edit them to see what happens if you change something. This is an awesome tool I don’t think enough people know about.

Continue reading »

 

Operations Manager has always been a fairly powerful tool. Even in it’s MOM2000 and MOM2005 variations it has a lot to offer. Sadly, in all the organizations I’ve been to, it’s never been utilized to it’s fullest.

I want to help change that.

Do you have a ‘batch’ server at your organization? You should. A batch server is a general all purpose scripting machine. It’s one you use to automate a lot of tasks that you don’t want to have a dedicated machine for, but are more important then you’d want to trust to run on your regular workstation. It doesn’t need to be anything particularly powerful – my batch server is a small Dell pizza box with now outdated hardware: Pentium 4 3.4Ghz CPU, maxed out at 2GB of ram, with an 80GB hard drive. Up until recently it ran Windows 2000 – it now runs Server 2008 standard.

A lot of the stuff I’ll be writing about will have a batch server in mind. I run these scripts there, and use OpsMgr to interact with the data. You’d be amazed at how much more you can accomplish and automate things with a simple ‘throw away’ desktop.

To start out, let’s get OpsMgr to record some stock prices. This will be a powershell script, that I’ll be running on our batch server. Read on to see how I do it.

Continue reading »

 

I would have posted this yesterday, but I wanted to do some testing first. Twelve hours ago the PowerShell team announced the release of V2 CTP3. It adds a lot of great things into the mix. I wanted to verify that it plays well with OpsMgr and as suspected it does.

Just a note – you’ll need to install PowerShell v1 for a new OpsMgr install. But you can then remove it and install a newer version. I typically run the newest v2 CTP release on my laptop, though I remain at v1 on the production servers.

Happy holidays all!

 

I’ve been working on a new, more condensed version of the OpsMgr PoSh library – one of the coolest features I think is the ‘location awareness’ which automatically switches your management server and such based on where you’re actually connected from.

Anyway, to do that I was embedding things in function prompt {}. In case you aren’t aware, if you define the prompt function, whatever is in there will run everytime you return to the prompt in the console. You can use this to your advantage for many things, such as this nifty little battery gauge that lets you know how much juice is left. It also has a configurable global variable, BatteryDisplayAtPercent, which you can set so it will hide until there is that much charge or less remaining.

First a screenshot, then the script:

battery-prompt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# ==============================================================================================
#
# Microsoft PowerShell Source File -- Created with SAPIEN Technologies PrimalScript 2007
#
# NAME: Battery-Prompt.ps1
#
# AUTHOR: Jeremy D. Pavleck , Pavleck.NET
# DATE  : 12/14/2008
#
# COMMENT: Lists the percentage of battery remaining above your prompt inside the console.
#    Difficulty level: OVER 9000!!!!!!!!!!!!!!!!
#
# ==============================================================================================
$GLOBAL:BatteryDisplayAtPercent = 101 # When you should start displaying status
# Anything over 100 means to show it all
Function GLOBAL:Get-BattLevel($minLevel) {
$charge = (Get-WmiObject -Class Win32_Battery).EstimatedChargeRemaining
If(!$charge) {break} # Not on a laptop, or no battery, so exit
Switch($charge) {
{($charge -ge 101) -and ($minLevel -ge 101)} {Write-Host "Batt: CHARGING" -ForeGroundColor Green}
{($charge -ge 80) -and ($charge -le 100) -and ($charge -le $minLevel)} {Write-Host "Batt: $charge%" -ForeGroundColor Green}
{($charge -ge 40) -and ($charge -le 79) -and ($charge -le $minLevel)} {Write-Host "Batt: $charge%" -ForeGroundColor Yellow}
{($charge -ge 16) -and ($charge -le 39) -and ($charge -le $minLevel)} {Write-Host "Batt: $charge%" -ForeGroundColor Magenta}
{($charge -ge 1) -and ($charge -le 15) -and ($charge -le $minLevel)} {Write-Host "Batt: $charge%" -ForeGroundColor Red}
default {break}
}
}
function prompt() {
Get-BattLevel $GLOBAL:BatteryDisplayAtPercent
}
 

No matter how careful you are. No matter how many times you’ve checked your parameters and state conditions. No matter how many times you tested it out of production.

It happens.

Some misconfigured rule – or even an event that happens much differently in a production environment then in test – begins firing off alerts.  Maybe you don’t notice it right away – perhaps you haven’t setup notifications for this particular rule.

But then, one day you start getting emails from your RMS with scary event IDs like 2115 (Data source not receiving a response), 25017 (Backlogged event processing) and 29202 (Inconsistent database state).

So you decide to investigate, and open up the Operations Console.

Only… wow, it’s running a lot slower then it normally does. Insanely slow.
You click onton Monitoring > Active Alerts – and then wait. And wait some more. As our once friendly green progress bar seems to start taunting you. So you lock the desktop and go chat up that new girl they hired. Wow, she’s pretty amazing right? Funny and smart as a whip, too.

Feeling happy and content after working your suave IT skills on her, you literally float back to your desk and unlock your desktop. Wasn’t there something bothering you before? Oh well, must have not been all that important. You peek up from your cube and catch a glimpse at her, then move those eyes down and see your still open Operations Console. The evil green bar still chugging away. But then you also see why…

A rogue rule quickly causes the alert count to soar to over 140,000

A rogue rule quickly causes the alert count to soar to over 140,000

And your nemesis, the green progress bar, it still keeps going. That number is rising faster then your blood pressure right now.

Must be a bug, eh? Ok, well, we’ll just check it via SQL to be sure – so you open SQL Studio and run

1
Select Count(*) from Alert

And then your informed, without any gentleness of a WWII nurse as depicted in the movies, that you have a lot of open alerts.

Over 250,000 alerts according to SQL

Over 250,000 alerts according to SQL

Wow! You better fix this!
And you better do it on the RMS, because it’s taking forever from your desktop.
You already have a general idea of which rule did it – that active alerts panel should be filled with it. So your first stop is to get back to authoring panel and either disable that rule or setup some proper alert suppression. Then we just have to deal with cleanup.

You turn, as always, to our friend PowerShell to help us out. Surely the easiest and most obvious solution to this problem is to run

1
2
3
4
5
$alerts = Get-Alert | Where-Object {$_.Name -match "MyRule"}
ForEach($alert in $alerts) {
$alert.ResolutionState = 255 # Close the alert
$alert.Update("")
}

Then just wait for the nightly alert grooming to happen to nudge it along with a SQL exec p_AlertGrooming

Only, when you try to do it, you get an OutOfMemory exception.

Out of memory!

Out of memory!

Now what to do?! The console is crippling slow – if you had to close the alerts that way your company would have gone bankrupt during the Dot Com Re-Burst of 2799! And when you try with PowerShell, you’ve run out of memory!

That’s where I was, until I talked to an unnamed friend((If you want to be named, just let me know. Better to err on the side of caution and all that)) from MS that really helped me out. That, combined with hindsight, allows me help you out as well!

How To Clean Up an Alert Storm

  1. Try the console. We’re going to assume it’s running slower than <Insert joke about large celebrities in the 1980s doing something they’re known for>, so we’ll move on.
  2. Try the Command Shell. $alerts = Get-Alert |? {($_.ResolutionState -eq 255) -or ($_.Name -match “Rule name if you know the naughty one”)}  – Running out of memory still?
  3. Try the same command, only instead of piping it to Where-Object, use the builtin filter object.
    $alerts = Get-Alert -criteria ‘WHERE ResolutionState = 0 AND Name LIKE ”%Rule Name%”’
  4. Still OOM? Try running both of those commands on the RMS, or another management server. Pick one with the most amount of memory, and hope for the best.
  5. Still receiving Out of Memory exceptions? Let’s stop using the OS to manage our memory. Open RegEdit and navigate to HKLM\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Config Service – change the value of Should Manage Memory from False to True. Stop and restart the config service.
  6. Now try your command again. It will take some time, but it will complete. Now lets try running the whole script to fix this:
    1
    2
    3
    4
    5
    $alerts = Get-Alert | Where-Object {($_.ResolutionState -eq 255) -and ($_.Name -match "MyRulename")}
    ForEach($alert in $alerts) {
    $alert.ResolutionState = 255
    $alert.Update("")
    }

    (Alternately, you can use the Resolve-Alert cmdLet, but from testing it’s not quite fast enough to keep up with the next step)
  7. Now when you ran step 6, it probably gave you a lot of errors when attempting to update the alert. That’s because there’s a small window of freshness to your alert object, and if you don’t update it within that window it becomes stale and unable to be used. To fix that, change the ForEach to look like this:
    ForEach($alert in $alerts) {
    $freshAlert = Get-Alert $alert.id
    $freshAlert.ResolutionState = 255
    $freshAlert.Update(“”)
    }
    That will grab a fresh version of that alert and update it.
  8. But what if you have thousands upon thousands of alerts? The above solutions could conceivably take days to run. Don’t worry, there’s a way around that, too.
    Before I show you, please be noted that this METHOD IS NOT SUPPORTED BY MICROSOFT and use of this method could possibly BLACKLIST YOUR OpsMgr INSTALL. It is the answer given out occasionally though, much to the dismay of the product group, so use that information how you’d like.
  9. Connect to your operations manager database and run the following update. This one updates every rule, but you could narrow it down with an additional AND WHERE RuleName = “My Rule Name”
    1
    2
    3
    Update Alert
    Set ResolutionState = 255
    Where ResolutionState = 0 and TimeResolved is Null
  10. When that’s completed, you’ll need to update the TimeResolved via:
    1
    2
    3
    Update Alert
    Set TimeResolved = '20-06-20 00:00:00.000'
    Where ResolutionState = 255 and TimeResolved is Null

    < Make TimeResolved be some day in the past so it will groom them out.
  11. Either wait overnight until the grooming jobs kick off or run
    1
    Exec p_AlertGrooming
  12. You’re done. Now don’t do it again!

[print_link]

 

I’ve been working on several things all in parallel, and I’ll give you a little insight into them all.

But first, don’t forget to enter the Pavleck.NET Contest for your chance to win 1 of two Amazon.Com gift cards. We’re currently at a paltry 10 entries, so your chances are pretty good to say the least. If I get a good turnout for this, I’ll make this a regular event – I already have next months prize ready, too. A rare copy of System Center Operations Manager 2007 Unleashed – signed by all the authors. Not many of these exist, but I have one for you!

What’s I’m working on:

  • Writing a small MOM 2005 to SCOM 2007 migration report script. Examines your agents from MOM and compares them with what’s installed in SCOM.
  • Attempting to write a small service that will handle custom alert notifications by matching alert names to notification groups through the SDK. A simple XML file is used to create the configuration, and it’s as easy to setup as this:
    XHTML
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    &lt;SCRAPPI&gt;
    &lt;MS&gt;
    &lt;RMS&gt;draco.pavleck.org&lt;/RMS&gt;
    &lt;/MS&gt;
    &lt;AlertMatrix&gt;
    &lt;alert matchType="Prefix"&gt;
    &lt;alertName&gt;My Custom Alert Prefix&lt;/alertName&gt;
    &lt;notiRecip&gt;f6f0278c-9bd7-874a-db18-cf85f2620c4d&lt;/notiRecip&gt;
    &lt;/alert&gt;
    &lt;/AlertMatrix&gt;
    &lt;/SCRAPPI&gt;
  • Work on SCOPE continues, including a partial command list – feel free to add to it.
  • As does an article (With a nifty flow chart!) of the steps to take to handle an alert storm, from the console all the way to SQL – get that system back in action!
 

When it comes to notifications, we have many options – except one that people have asked about, a nag mode. Something that will re-send an email after a certain amount of time to make sure it’s taken care of.

Well, it does exist in OpsMgr.

Either intentionally or unintentionally as a bug, if you call the Update method on an alert without changing any criteria, the notification bound to the alert will re-fire. This will happen whether you add a comment with the update (Update(“Updating the alert”)) or not (Update(“”)).

To enable this secret nag-mode, it’s as simple as writing a Powershell script that runs every X hours. In that script you’ll just need to do a Get-Alert with the criteria you’re looking for – in the example I’m just going to have it return all alerts older then 4 hours, and update them.

It’s very simple though – how simple? Like this:

1
2
3
4
$oldAlerts = Get-Alert | Where-Object {($_.LastModified -ge [DateTime]::Now.AddHours(-4)) -and ($_.ResolutionState -eq 0)}
ForEach($alert in $oldAlerts) {
$alert.Update("")
}

You can expand this as much as you’d like. Match against NetBiosComputerName to only nag for those critical core servers, match it against the monitoring object to ensure critical monitors are being addressed. Multiple management groups? Match against that. You see where I’m going with this. In fact, you can find out everything you can match against by just running Get-Alert | select -first 1 – there’s all the fields available.

© 2012 Pavleck.NET Suffusion theme by Sayontan Sinha