About the author

Author Name is someone.
E-mail me Send mail

Recent posts

Recent comments

Don't show

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Custom objects, custom formatting

One of the things that comes up quite often in my PowerShell classes is using your own .Net types so I though I'd put up a couple of entries based on a demo that I do.

I've put a zip file with all of the code mentioned in these posts into my download area.

I created a small .Net assembly containing two types, Bank and Account.

and compiled them into a file called Accounts.dll.

Now I can use Reflection.Assembly to load the dll

and create and use objects from the assembly

In the next post I'll add a custom format file so that negative bank account balances are displayed a (1000) rather than -1000.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by tb on Monday, March 03, 2008 2:13 AM
Permalink | Comments (0) | Post RSSRSS comment feed

PowerShell support in SQL 2008

I've just been looking at the PowerShell support and it looks interesting if a little limited - as has been stated in Dmitry’s PowerBlog.

You invoke PowerShell from SQL Server Management Studio by right clicking on a node in the tree and choosing 'Start PowerShell'. This runs 'SQLPS.exe' and starts the shell. One thing that caught me was that the resulting shell has some standard cmdlets missing. Add-PSSnapin, Get-PSSnapin, Remove-PSSnapin and Export-Console seem to have gone AWOL.

SQL Books Online states that the SQL snapins are

  • Microsoft.SqlServer.Management.PSProvider.dll
  • Microsoft.SqlServer.Management.PSSnapin.dll

As these are just regular snapins you can load them into the standard PowerShell host as follows -
First register the snapins using the .Net utility installutil with the commands

set-alias installutil $env:windir\Microsoft.NET\Framework\v2.0.50727\installutil
cd "c:\Program Files\Microsoft SQL Server\100\Tools\Binn"
installutil Microsoft.SqlServer.Management.PSProvider.dll
installutil Microsoft.SqlServer.Management.PSSnapins.dll

and check that everything is OK


Registering SQL snapins

Then load the snapins

Installing the SQL snapins

and voila SQL support is enabled

SQL support working

Don't forget to remove and unregister (installutil /u) the snapins when you want to remove the CTP.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: PowerShell | SQL 2008
Posted by tb on Monday, February 25, 2008 1:23 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Getting through a proxy server with PowerShell

When we were looking at using the System.Net.WebClient class to retrieve web pages the question "how do you use this when you have to go through a proxy server and provide credentials?" came up.

A little bit of exploration with get-member and some digging in MSDN revealed that

  • the System.Net.WebClient class has a proxy property that can be set to an instance of the System.Net.WebProxyClass
  • the System.Net.WebProxyClass has a credentials property that can be set to an instance of any object that implements the ICredentials interface
  • The class System.Net.NetworkCredential implements ICredentials
  • the get-credential cmdlet returns a System.Management.Automation.PSCredential object
  • the PSCredential class has a method called GetNetworkCredential that returns a System.Net.NetworkCredential object - just what we need :-)

  Putting all of that together gives us this script which will ask for credentials and feed them to a proxy server.

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Net")
#
# Create a proxy object
#
$proxy = new-object System.Net.WebProxy
#
# Grab some credentials and store them in the proxy object
#
$cred = get-credential
$proxy.credentials = $cred.GetNetworkCredential()
#
# Off to the web
#
$WebClient = new-object System.Net.WebClient
$WebClient.proxy = $proxy
$url = "http://www.microsoft.com"
$content = $WebClient.DownloadString($url)

It just goes to show how great the combination of PowerShell and the .Net framework is!

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by tb on Monday, January 07, 2008 3:53 AM
Permalink | Comments (0) | Post RSSRSS comment feed

A forms designer for PowerShell

I've just finished a great week teaching Mastering PowerShell for HBOS and a couple of interesting things came up.

When I teach the Windows.Forms module I usually show how easy it is to use one of the Visual Studio Express editions to build a form and then translate the designer generated code into PowerShell. This time however one of  the delegates pointed me at the Admin Script Editor which has a forms designer that generates native PowerShell script code :-)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by tb on Monday, January 07, 2008 3:51 AM
Permalink | Comments (0) | Post RSSRSS comment feed

The PowerShell 2.0 CTP is here!

You can download it from here

There are a couple of new posts from the PowerShell team that give some more information about this preview release

The first thing that catches my eye is a new version of get-wmiobject that adds in some of the sorely missed functionality of the COM interface to WMI. Hopefully the WMI interface also has some bug fixes.

Congratulations to the PowerShell team.

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: PowerShell | CTP
Posted by tb on Monday, January 07, 2008 3:50 AM
Permalink | Comments (0) | Post RSSRSS comment feed

The PowerShell 2.0 CTP is nearly here!

Check out these messages from Jeffrey Snover

Start building your VMs :-)

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: PowerShell | CTP
Posted by tb on Monday, January 07, 2008 3:48 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Launching PowerShell Scripts in Response to WMI Events

This turns out to very straightforward, the key is to use the CommandLineEventConsumer class. It allows you to launch any program in response to a WMI event. In order to use it you only need to set two properties (although there are many more to explore)

  1. Name - a unique name for your class instance
  2. CommandLineTemplate - the command you want to run

As we want to launch a PowerShell script the command line would need to be something like

powershell.exe -command C:\temp\myscript.ps1

This would run the script myscript.ps1 and pass it any parameters that are added to the command line. Within the script you can access the parameters via the $args array.

A Working Example

Lets say that we wanted to stop people running Solitaire on their PCs - it's mean but hey, we're admins! The PowerShell cmdlet stop-process will kill a process if we supply the process ID so we'll pass that out from WMI to the script and pick it up via $args.

stop-process $args[0]

As before you need to create a filter and a consumer and join them together. So this code creates a filter that looks for instances of Solitaire starting up

$EFClass = [wmiclass]"\root\subscription:__EventFilter"
$ef = $EFClass.CreateInstance()
$ef.Name = "NewProcessFilter"
$ef.Querylanguage = "WQL"
$ef.Query = "select * from __InstanceCreationEvent within 5 where targetinstance isa 'Win32_Process' and targetinstance.name = 'Solitaire.exe'"
$ef.EventNamespace = "root\cimv2"
$ef.put()

Next we create a consumer, using the CommandLineEventConsumer class. %TargetInstance.Handle% picks up the process ID from the win32_process object that triggered the event and adds it onto the end of the PowerShell command line.

$CLECClass = [wmiclass]"\root\subscription:CommandLineEventConsumer"
$clec = $CLECClass.CreateInstance()
$clec.Name = "RunPowerShell"
$clec.CommandLineTemplate = "powershell.exe -command C:\temp\myscript.ps1 %TargetInstance.Handle%"
$clec.put()

and finally join them together with an instance of the __FilterToConsumerBinding class

$FCBClass = [wmiclass]"\root\subscription:__FilterToConsumerBinding"
$fcb = $FCBClass.createinstance()
$fcb.Consumer = $clec.__Path
$fcb.Filter = $ef.__Path
$fcb.put()

Now every time you start Solitaire the PowerShell script myscript.ps1 will run and Solitaire will be terminated :-)

Note

You might get the same errors that I noted in an earlier post when you invoke the put method. This is a known bug in PowerShell 1.0 and will be fixed in v2.0. The workaround for now is to keep invoking put until it works.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: events | PowerShell | WMI
Posted by tb on Monday, January 07, 2008 3:41 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Power GUI

Check out PowerGUI a cool new free extensible GUI host for PowerShell from Quest. See it in action here.

Imagine an MMC like interface where each leaf node in the tree on the left hand pane is a PowerShell script or cmdlet and the right hand pane shows the results in tabuar form with the ability to filter and export. It comes bundled with extensions for managing Exchange 2007, Operations Manager 2007, local systems and Active Directory computers.

It's a little bit buggy at the moment but it has just made the job of building your own PowerShell based management tools so much easier :-)

But isn't there something slightly odd about hiding the command prompt behind a GUI...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: PowerShell | PowerGUI
Posted by tb on Monday, January 07, 2008 3:29 AM
Permalink | Comments (0) | Post RSSRSS comment feed

A first look at WMI events

Event notification is built into WMI and if you open up CIM Studio (one of the tools in the WMI Toolkit) and navigate to '__SystemClass\__IndicationRelated' you will find all of the classes related to event handling. There are two types of event that you can use -

Intrinsic Events

These are generated by WMI in response to changes in the CIM repository and further breakdown into events related to namespaces, classes, instances and timers. You can see these by navigating to '__SystemClass\__IndicationRelated\__Event' where you will find

  • __NamespaceOperationEvent and its children
  • __ClassOperationEvent and its children
  • __InstanceOperationEvent and its children
  • __TimerEvent

If you poke around under these classes you'll see that there are various events that fire when something interesting happens in the CIM repository. The timer event is different as this lets you set up an event that fires on a regular basis or at a scheduled time.

Extrinsic Events

Providers

Extrinsic events are fired into WMI by providers. Providers allow third parties to plug in to WMI and make their management information available. You'll probably have a whole bunch of these registered on your systems. They are often created as DLLs with an accompanying MOF file. You can find some provider related files in '%windir%\system32\wbem'. Look for any files with 'prov' in their names. Alternatively running these commands will give you an exhaustive list of the providers installed in the 'root\CIMv2' namespace from WMIs perspective.


get-wmiobject -class "__InstanceProviderRegistration" | select-object -property Provider
get-wmiobject -class "__ClassProviderRegistration" | select-object -property Provider
get-wmiobject -class "__EventProviderRegistration" | select-object -property Provider
get-wmiobject -class "__MethodProviderRegistration" | select-object -property Provider
get-wmiobject -class "__PropertyProviderRegistration" | select-object -property Provider
get-wmiobject -class "__EventConsumerProviderRegistration" | select-object -property Provider
and Events

In order to list all of the extrinsic events available on a system you need to recurse through all of the namespaces in WMI listing out all of the '__ExtrinsicEvent' classes that you find. This next piece of code does exactly that. It uses a couple of functions -

Get-ExtrinsicEvents
runs a query against all of the classes in a particular namespace and lists only the '__ExtrinsicEvent' classes. Specifying 'meta-class' causes Get-WmiObject to retrieve class rather than instance objects from the repository.
ExamineNamespace
recurses through a namespace hierarchy calling Get-ExtrinsicEvents

function Get-ExtrinsicEvents( [string]$ns )
{
Get-WmiObject -class meta_class
-namespace $ns
-filter "__this isa '__ExtrinsicEvent'" |
select-object Name | Format-Table -HideTableHeaders
}

function ExamineNamespace( [string]$ns )
{
write-host "==================" $ns
Get-ExtrinsicEvents $ns

foreach ($n in (Get-WmiObject -Class "__NAMESPACE" -namespace $ns))
{
ExamineNamespace ($n.__NAMESPACE + "\" + $n.Name)
}
}

ExamineNamespace "ROOT"

In my next post I'll look at how you register you interest in specific WMI events and how you can launch PowerShell scripts in response to WMI events.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: events | PowerShell | WMI
Posted by tb on Monday, January 07, 2008 2:32 AM
Permalink | Comments (0) | Post RSSRSS comment feed

WMI events and PowerShell

I see on the Powershell Team blog Kapil Mathur is writing about his experience with WMI and Powershell. I find when I'm out and about teaching and consulting that very few people have explored WMI and even fewer make use of it.

I think WMI is one of the most useful technologies to be able to script against and over the next week or two I'm going to look at the WMI event model and how to use WMI to invoke Powershell scripts in response to WMI events. I'll also look at how you can use Powershell to audit all of the events handlers that have been registered on your systems.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: PowerShell | WMI
Posted by tb on Monday, January 07, 2008 2:31 AM
Permalink | Comments (0) | Post RSSRSS comment feed