Ying Li(MVP) at myITforum.com

PowerShell & System Center

April 2008 - Posts

PowerShell one liner to close ~3000 SCOM alerts!

As I mentioned before, I was in Seattle for Global MVP Summit 2008 last week. So I left SCOM behind. One of my coworkers moved some DB to a different SQL box and without disabling the job associates with it – We got about ~3000 alerts for this until I disable the alert. When I try to clean up this mess. I started with the GUI way – select them in bunch and close alerts. Then I am getting tired of it and I talk to myself - why not use PowerShell? I come up with the below one liner and the alerts gone in no time!

get-alert |where {$_.netbioscomputername -eq 'xyz'} | resolve -alert

PowerShell to identify the GlobalCatalog Servers and more in your AD environment - Part II

Lets continue play with AD using PowerShell.

PS C:\Documents and Settings\yl.admin\My Documents\PS>$myforest = [System.DirectoryServices.AcitveDirectory.Forest]::GetCurrentForest()

PS C:\Documents and Settings\yl.admin\My Documents\PS> $myforest.Sites


Name                           : NYT
Domains                        : {mydomain.com}
Subnets                        : {xxx.yyy.0/16}
Servers                        : {dc1.mydomain.com, NYTDCP01.mydomain.com, NYTDCP02.mydomain.com, dc2.mydomain.com}
AdjacentSites                  : {COA, NYH, NJC, NYR...}
SiteLinks                      : {NYT-To-COP-10, NYT-To-NJC-10, NYT-To-NY5-10, NYT-To-NYB-10...}
InterSiteTopologyGenerator     : NYTDCP02.mydomain.com
Options                        : None
Location                       : NY/TW
BridgeheadServers              : {NYTDCP02.mydomain.com, NYTDCP01.mydomain.com, dc1.mydomain.com, dc2.mydomain.com}
PreferredSmtpBridgeheadServers : {}
PreferredRpcBridgeheadServers  : {}
IntraSiteReplicationSchedule   :

Name                           : NJC
Domains                        : {mydomain.com}
Subnets                        : {}
Servers                        : {njc.mydomain.com}
AdjacentSites                  : {NYH, NYT, CAL, CAG...}
SiteLinks                      : {NYT-To-NJC-10, NJC-To-CAL-100, NJC-To-CAG-100, NJC-To-CAI-100...}
InterSiteTopologyGenerator     : njcdcp01.mydomain.com
Options                        : None
Location                       : New Jersey
BridgeheadServers              : {njcdcp01.mydomain.com}
PreferredSmtpBridgeheadServers : {}
PreferredRpcBridgeheadServers  : {}
IntraSiteReplicationSchedule   :

 .

.

Two things I don’t like about the output is:

1) The format

2) What about the information after … – we simply can’t see!

 So I gathered enough strength and time to write a script to get the output into excel format which I like (My bosses like too!) and to enumerate through those arrays to get complete information:

$a = New-Object -comobject Excel.Application
$a.visible = $True

$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)

$c.Cells.Item(1,1) = "SiteName"
$c.Cells.Item(1,2) = "Domains"
$c.Cells.Item(1,3) = "Subnets"
$c.Cells.Item(1,4) = "Servers"
$c.Cells.Item(1,5) = "AdjacentSites"
$c.Cells.Item(1,6) = "SiteLinks"
$c.Cells.Item(1,7) = "ISTG"
$c.Cells.Item(1,8) = "Location"
$c.Cells.Item(1,9) = "BridgeheadServers"
$c.Cells.Item(1,10) = "Report Time Stamp"


$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True

$intRow = 2

$MyForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$Sites = MyForest.Sites
Foreach($Site in $Sites)
{
$c.Cells.Item($intRow,1)  = $Site.Name
 Foreach ($domain in $Site.domains)
 {$Dom+=$domain.name + ";"
  $c.Cells.Item($intRow,2)  = $Dom}

 Foreach($Subnet in $Site.Subnets)
 {$Sub+=$Subnet.name + ";"
         $c.Cells.Item($intRow,3)  = $Sub}

 Foreach($Server in $Site.Servers)
 {$Ser+=$Server.name + ";"
  $c.Cells.Item($intRow,4)  = $Ser}

 Foreach($adjacentSite in $site.adjacentSites)
 {$adj+= $adjacentSite.name + ";" 
  $c.Cells.Item($intRow,5)  = $Adj}

 Foreach($SiteLink in $Site.SiteLinks)
 {$Sit += $SiteLink.name + ";"
  $c.Cells.Item($intRow,6)  = $Sit}

$c.Cells.Item($intRow,7)  = $Site.InterSiteTopologyGenerator.name
$c.Cells.Item($intRow,8)  = $Site.Location

 Foreach($BridgeHead in $Site.BridgeheadServers)
 {$Bri += $BridgeHead.name + ";"
  $c.Cells.Item($intRow,9)  = $Bri}

$c.Cells.Item($intRow,10) = Get-date

$Dom = $null
$Sub = $null
$Ser = $null
$adj = $null
$Sit = $null
$Bri = $null
 
$intRow = $intRow + 1


}
$d.EntireColumn.AutoFit()

 


 

 

 

Posted: Apr 21 2008, 07:47 PM by yli628 | with no comments
Filed under: ,
MVP Global Summit 2008 - Virtualizes everything and PowerShell everywhere

I just came back from a week trip to Seattle for MVP Global Summit 2008. It was a four days event with intense and fun activities. I am exhausted but enlightened. I am very glad that I went!

 

After initial awkwardness, as this is my first MVP summit and I know a lot people digitally but none physically. Trust me, Wandering among ~2000 people by yourself is not something you will enjoy. Well, that situation changed when I met my fellow myITforumers. I felt I found my home team! These are a group of interesting people by every means - Ron Crumbaker(co-owner of myITforum in case you don't already know), April Cook, Anthony Clendensen(Flew from Arizona with only one T shirt on him, from ~90 F in Arizona to ~40 F in Seattle, He will have a lot adjustment to do. We joked about if he could make it through with that one T shirt. I had my leather jacket on me the entire time, I was still feeling cold!)Sherry Kissinger, Garth Jones (from Canada, a very funny guy!) Greg Ramsey (I thought we are going to go to Space Needle together, LOL), Chris Mosby, Brian Mason; Ed Aldrich and Steve Thompson, fellow New Englanders. Unfortunately Rod Trent and Don Hite didn't make it.

 

Most my fellow myITforumers are SMS MVP except Steve are SQL MVP. As an admin framework MVP myself, most of my sessions were with PowerShell team. The upside is that I get to meet another group of interesting people; the downside is that I have to depart from my newly found home team. That is not as easy as you would think. As a shy and quiet rooky MVP, that's not easy at all! :)

 

Well, I have to overcome my born weakness and as always it comes with very rewarding experience. I had the honor to meet PowerShell partner architect Jeffrey Snover, Bruce Payette (Author - PowerShell in Action) and Lee Holmes (Author -PowerShell Cookbook). I have the pictures as a proof! LOL! I have the opportunity to discuss with different Microsoft product team such as AD, WMI, Exchange, IIS, SQL...

 

I also have the chances to meet my fellow admin framework MVPs and these are some folks with great accomplishments(So are my fellow myITforumers!). They are Book authors, Trainers and business owners, Among them are Charlie Russell(Canada), Thomas Lee(UK), Don Jones, Jeffrey Hicks, Dimitry Sotnikov(Russia) Arnaud Petitjean (French) just to name a few...

 

We enjoyed the best Sushi place (Tuna House) in Seattle. Thanks Thomas Lee for pointing to the right direction and thanks Jeffrey to pay for it of course. LOL! After pour in a few rounds of sakes, I realized that I am not that shy after all!

 

Ah, I have to mention Olaf Engelke, a fellow MVP from Germany and he is responsible to take all the pictures. So if you see any pictures from the MVP summit website later on, most likely they were taken by Oilskin. Thanks Olaf for the great memory!

 

Also I would like to thanks Refaat Issa, a Project Manager from Microsoft PowerShell team to coordinate all the sessions with different product team!

 

Opps, I almost forgot my MVP lead Mark Clagett, a bright young fellow.

 

Last but not least, we have the opportunity to listen the keynote speech from Ray Ozzie (Chief Software Architect) and Steve Ballmer (CEO). WOW, Steve is the most funny and contagious CEO I have ever seen.

 

Thanks Microsoft for the great experience!

 

Well enough said about the event flow. The key take away from this event for me is that Microsoft will invest aggressively on Virtualization. MS will try to virtualize the world, well IT world at least:

 

Server Virtualization (Microsoft Virtual Server 2005 R2 and the upcoming release Windows Server 2008 Hyper-V)

Desktop Virtualization (Kidaro)

Application Virtualization (Softricity)

Presentation Virtualization

 

Another key take away for me is, you guess it, - PowerShell everywhere!

 

Microsoft PowerShell team will work with all the other major product team to extend the PowerShell support in the next release - such as AD, IIS 7, SQL 2008 etc.

Posted: Apr 21 2008, 12:22 AM by yli628 | with no comments
Filed under: ,
PowerShell to identify the GlobalCatalog Servers and more in your AD environment - Part I

I recently started a new job (about two months for now). As you would imagine, I would have a lot questions. Some of them related to AD. How the AD setup? What’s the domain /forest function level? How many sites? Where are the GlobalCatalog Servers or BridgeHeadServers? etc.

How can I get those informations?

Ask coworkers is one option, What if they are busy and they don’t know these information on top of their head?

Of course, we can go to Active Directory Sites and Services and go to each server – right click NTDS settings-properties to find the GCs. That would be a little awkward in 21st Century, don’t you think?

For GCs, I can do a NSLOOKUP gc._msdcs.mydomain, it give me a bunch of IP Addresses.

Well, don’t forget we are in PowerShell Times!

$myforest = [System.DirectoryServices.AcitveDirectory.Forest]::GetCurrentForest()

 Initially I got “Unable to find type [System.DirectoryServices.AcitveDirectory.Forest]: make sure that the assembly containing this type
 is loaded.”

No Problem, I know how to handle that – run the below script first

if (-not ([appdomain]::CurrentDomain.getassemblies() |? {$_.ManifestModule -like “System.DirectoryServices.ActiveDirectory.Forest”})) {[void][System.Reflection.Assembly]::LoadWithPartialName(’System.DirectoryServices.ActiveDirectory.Forest’)}

Run the above script again:

PS C:\Documents and Settings\yl.admin\My Documents\PS>  $myforest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
PS C:\Documents and Settings\yl.admin\My Documents\PS> $myforest

Name                  : mydomain.com
Sites                 : {NYW, NCR, NYS, CAG...}
Domains               : {mydomain.com}
GlobalCatalogs        : {abc.mydomain.com; xyz.mydomain.com…}                        .}
ApplicationPartitions : {DC=ForestDnsZones,DC=related,DC=com, DC=DomainDnsZones,DC=related,DC=com}
ForestMode            : Windows2000Forest
RootDomain            : mydomain.com.com
Schema                : CN=Schema,CN=Configuration,DC=related,DC=com
SchemaRoleOwner       : xyz.mydomain.com
NamingRoleOwner       : xyz.mydomain.com

How about

PS C:\Documents and Settings\yl.admin\My Documents\PS> $myforest.Sites

and

PS C:\Documents and Settings\yl.admin\My Documents\PS> $myforest | gm

Fun starts from here and sky is your limit! – to be continue…

Posted: Apr 09 2008, 06:09 PM by yli628 | with no comments
Filed under: ,
Re-Uniting PowerShell Consoles on your Computer

I have Exchange 2007 Administrator tool and SCOM administrator tool installed on my computer. Both come with a GUI console and a PowerShell console. On top of that, I have my regular PowerShell console.

Before I have to juggle between these three PS consoles to accomplish different daily tasks. Well, not any more!

Go to Start – All Programs – Windows PowerShell v2(CTP) – right click on Windows PowerShell v2(CTP)– Windows PowerShell v2(CTP)Properties -Target, here is what’s there

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe

Do the similar thing for SCOM 2007 and Exchange 2007, you get below text respectively:

C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile Microsoft.EnterpriseManagement.OperationsManager.ClientShell.Console.psc1 -NoExit .\Microsoft.EnterpriseManagement.OperationsManager.ClientShell.Startup.ps1

C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell.exe -PSConsoleFile "C:\Program Files\Microsoft\Exchange Server\bin\exshell.psc1" -noexit -command ". 'C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1'"

As you can see, there nothing more special about SCOM and Exchange – They are using the same PowerShell console (PowerShell.exe) except they add their console file respectively. Console files are xml files with psc1 extensions, they store configuration setting for their application specific consoles.

Here is how I use one console to do all my jobs:

Start the regular PowerShell Console

PS C:\Documents and Settings\yl.admin\My Documents\PS>

I then run addExSnapin.ps1 script which has only one line in it –

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin

PS C:\Documents and Settings\yl.admin\MyDocuments\PS> .\AddExSnapin.ps1

I go back to the same prompt except now I can run Exchange cmdlets

PS C:\Documents and Settings\yl.admin\My Documents\PS> Get-MailboxDatabase

Name                 Server          StorageGroup         Recovery
----                 ------          ------------         --------
CES01 SG01 DB        xyz01      CES01 SG01           False
CES01 SG02 DB        xyz01     CES01 SG02           False

.

.

I then run a script AddConnSCOMSnapin.ps1:

Add-PSSnapin "Microsoft.EnterpriseManagement.OperationsManager.Client"
Set-Location "OperationsManagerMonitoring::"
$rootMS = "XYZOPMP01"
new-managementGroupConnection -ConnectionString:$rootMS
Set-Location $rootMS


PS C:\Documents and Settings\yl.admin\My Documents\PS> .\AddConnSCOMSnapin.ps1

PathName             :
ManagementGroup      : XYZ Enterprise Apps
ManagementServerName : XYZOPMP01
Drives               :

PS Microsoft.EnterpriseManagement.OperationsManager.Client\OperationsManagerMonitoring::XYZOPMP01> get-agent| where-obj
ect {$_.name -match "mbx"}


PrimaryManagementServerName           : xyzopmp04.contoso.com
Id                                    : 3e8e5503-3437-22d3-669f-2209b8a71694
LastModified                          : 4/7/2008 10:41:50 PM
Name                                  : xyzMBXP01.contoso.com
DisplayName                           : xyzMBXP01.contoso.com
HostComputer                          : xyzMBXP01.contoso.com
HostedHealthService                   : xyzMBXP01.contoso.com
HealthState                           : Error
PrincipalName                         : xyzMBXP01.contoso.com
NetworkName                           : xyzMBXP01.contoso.com
ComputerName                          : xyzMBXP01.contoso.com
.

.

If I want swich back?

PS Microsoft.EnterpriseManagement.OperationsManager.Client\OperationsManagerMonitoring::XYZOPMP01> cd "C:\Documents and
 Settings\yl.admin\My Documents\PS"
PS C:\Documents and Settings\yl.admin\My Documents\PS>

Whoa, now I can use one PS console and easily swich back and forth between all my daily administration tasks!

Configuring Kerberos Authentication for SharePoint Integrated Reporing

After successfully implemented SCOM Reporting Server (with some help of course!) I get my hands dirty with SharePoint Reporting Server. I was trying to setup a Reporting Server in SharePoint Integrated Mode in our testing SharePoint Environment. In our testing environment, I already have a SharePoint Server(hosting the Central Administration Site), a FrontEnd and a SQL DB server setup.

SETSPN part has already been done to ready our SharePoint environment for Kerberos authentication.

In order to do this SETSPN.EXE needs to be installed on a server and run by an Active Directory Administrator for all App Pool accounts and SSP sites using those App Pools.  SETSPN.EXE is available in the Windows Server 2003 Support Tools that are included on the Windows Server 2003 CD. To install the tools, double-click the Suptools.msi file in the Support/Tools folder.   

You will need domain admin right to do this: The sites need to have two Server Principal Names associated, one using the FQDN (collaboration.contoso.com) of the server name one using just the server’s netbios name (the FQDN without the .contoso.com e.g. collaboration). 

Here is some good reading regarding this topic Configuring Kerberos for SharePoint 2007

But that is not my focus here. After I followed Microsoft SQL Server Reporting Services - Installation and Configuration Guide for SharePoint Integration Mode The reporting server is almost up except that every time I go to the “Set Server Defaults” page through SharePoint Central Administration, I got the below error:

“An unexpected error occurred while connecting to the report server. Verify that the report server is available and configured for SharePoint integrated mode. --> Server was unable to process request. ---> The request failed with HTTP status 401: Unauthorized. “

I know the report server is available and configured for SharePoint integrated mode. I know this has something to do with the Kerberos/NTLM authentication. I even remembered to do SETSPN for this new reporting server and the related SharePoint account but still NO LUCK!

It turns out that I did the SETSPN part wrong:

SETSPN.exe -a http/%SharePointReportServerFQDN&Port% Domain\%AssociatedAccount%

SETSPN.exe -a http/%SharePointReportServer&Port% Domain\%AssociatedAccount%

Since I set up the Reporting Server to use port 8081 so it was very “logical” to me to only registered for port 8081 which turns out not correct. What we need to do here is to just register the reporting servers’ FQDN name and netbios name with relevant accounts. and we don’t need to put port number there!!!

 

SETSPN.exe -a http/%SharePointReportServerFQDN% Domain\%AssociatedAccount%

SETSPN.exe -a http/%SharePointReportServer% Domain\%AssociatedAccount%

   
 
 

Posted: Apr 06 2008, 10:34 PM by yli628 | with no comments
Filed under:
PowerShell script to put the Server, the Health Service and the Health Service Watcher on that server into maintenance mode

In my previous post Schedule a maintenance window I described using PowerShell cmdlet to schedule a maintenance window for target client.

jgoodson made the below comment:

“The script worked great. Can you expand it to set maintenance within Health Service and Health Service Watcher per KB 942866 to cut out Heartbeat Notifications?”

Unfortunately I just noticed this comment today but here is my update:

KB942866

Here is the new script. This is the combined and modified script from my above script and the script from http://scom2k7.blogspot.com/2007/08/new-maintenance-mode-tool-for.html whoever the original author might be.

param($rootMS,$computerPrincipalName,$numberOfHoursInMaintenanceMode,$comment)

#You only need to do this next line once if you haven’t done so already and this is meant to add the Snapin for SCOM to your regular PowerShell console

Add-PSSnapin "Microsoft.EnterpriseManagement.OperationsManager.Client" -ErrorVariable errSnapin;


Set-Location "OperationsManagerMonitoring::" -ErrorVariable errSnapin;
new-managementGroupConnection -ConnectionString:$rootMS -ErrorVariable errSnapin;
set-location $rootMS -ErrorVariable errSnapin;

$computer  = Get-Agent | Where-object {$_.PrincipalName –eq $computerPrincipalName}
$healthService = $computer.HostedHealthService
$healthServiceWatcherClass = get-monitoringclass -name:Microsoft.SystemCenter.HealthServiceWatcher
$healthServiceCriteria = "HealthServiceName='" + $computerPrincipalName + "'"
$healthServiceWatcher = get-monitoringobject -monitoringclass:$healthServiceWatcherClass -criteria:$healthServiceCriteria
$startTime = [System.DateTime]::Now
$endTime = $startTime.AddHours($numberOfHoursInMaintenanceMode)


"Putting " + $computerPrincipalName + " into maintenance mode"
New-MaintenanceWindow -startTime:$startTime -endTime:$endTime -monitoringObject:$computer.HostComputer -comment:$comment

 
"Putting the associated health service into maintenance mode"
New-MaintenanceWindow -startTime:$startTime -endTime:$endTime -monitoringObject:$healthService -comment:$comment

 
"Putting the associated health service watcher into maintenance mode"
New-MaintenanceWindow -startTime:$startTime -endTime:$endTime -monitoringObject:$healthServiceWatcher -comment:$comment

#To confirm your result and the retuned time is Universal Time

Get-MaintenanceWindow -MonitoringObject $computer.hostcomputer

You can save the above script to your default PowerShell start directory and run the script from there and provice the variables…

One more bump on the SCOM Reporting Road

As in my previous post, I thought I get our SCOM Reporting up and running and so I was running away.

http://myitforum.com/cs2/blogs/yli628/archive/2008/03/26/another-bump-for-scom-reporting.aspx

I have a busy schedule and have to juggle between different projects/products – SCOM, SharePoint, Exchange, VMware , IIS just to name a few. When I get back to work on SCOM Reporting the other day and it is to my unpleasant surprise and I found everything stopped working. I can’t run reports any more and I was getting “object reference not set to an incidence of an object” error every time I am trying to run a report.

I was poking around and tried a few thing with no luck. The good thing is that I have my previous case with PSS “archived”. I turn to MS for the rescue. The guy was nice enough to offer me a suggestion to try. Bingo! They did it again!

What happen was after previous reinstalling ASP.NET, it took away the wild card mapping from the ReportServer virtual Directory-Configuration settings. After I added back the wild card mapping to aspnet_isapi.dll. Everything is working again!

So happily ever after with SCOM Reporting? I would like to dream that!

Posted: Apr 03 2008, 11:57 PM by yli628 | with no comments
Filed under:
SharePoint "Send To > Email a Link" Fix

In SharePoint 2007 Document Library, the Send To > Email a Link context menu will open your local email client and put the link of that document in the email body. But somehow the URL encodes the whole URL, instead of just the relative path. So the URL will end up like this:

http://sharepoint%2Exyz%2Ecom/devacct/Shared%20Documents/JDE%20-%20Timberline%20Conversion/JDE%20Standard%20Reporting%20Details.pdf

 

Basically, the dot(.) in the domain name is also URL encoded(%2E).

 

It is not clickable link even though if we copy it to IE, it will still work.

 

The link should be

http://sharepoint.xyz.com/devacct/Shared%20Documents/JDE%20-%20Timberline%20Conversion/JDE%20Standard%20Reporting%20Details.pdf

In order to fix this. You need to locate CORE.js in

 C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033

Make a backup copy of this file before you make any changes!

Find this line:

fileUrl=escapeProperly(httpRootWithSlash.substr(0, slashLoc))+currentItemUrl;

and replace it with this:

fileUrl=httpRootWithSlash.substr(0, slashLoc)+currentItemUrl;

 

You need to do the same on all the SharePoint frontend servers and SharePoint Application server.

After you done modifying the CORE.js file, you will need to do IISRESET on all the above servers.

Once all done, please verify the “Send To> Email a Link” function works the way it should!

Thanks Calvin998 for posting the  Send To > Email a Link Fix