/\/\o\/\/ PowerShelled

This blog has moved to http://ThePowerShellGuy.com Greetings /\/\o\/\/
$AtomFeed = ("Atom.xml")
$PreviousItems = (" Moving to ThePowerShellGuy.com "," PowerShell Code formatting test for my new Blog "," PowerShell Code formatting test for my new Blog "," PowerShell Community Extensions V1.0 "," PowerShell : Access remote eventlogs "," Windows PowerShell Scripting Sweepstakes! "," PowerShell : making Custum Enums "," TechNet Webcast: An Overview of Windows PowerShell "," "Windows PowerShell: TFM" goes "Gold" "," PowerShell : Advanced renaming of files "," ")

Friday, April 28, 2006


PowerShell in Action

Bruce Payette, a member of the PowerShell team is Writing a book about PowerShell :

PowerShell in Action, You can also find an Unedited Draft of Chapter 1 (Welcome to PowerShell).

I realy liked the background information about PowerShell in this chapter, it does explain the "Why" behind PowerShell and where it came from very well.

so a recommended read if you are looking for information about PowerShell


gr /\/\o\/\/
Tags :


Thursday, April 27, 2006


PowerShell out-PropertyGrid (MSH view-Object)

As with the switch from Monad to PowerShell there where some breaking changes, I have started a walk trough my blog history, and will re-do some of the scripts.
I will start with the first script on my blog :
MSH Object Viewer

I posted this script also on the NG some time before, and got a great suprise when I did watch the second Channel 9 video with Jeffrey Snover :
MSHObjectViewer mentioned in More talking about Monad (links to all the channel 9 videos you can find in the $links section in the bottom of the blog)

The script will take a Object from the commandline (If you use the PowerShell Analyzer or VS it will look familiar ;-))

B.T.W. Karl did also update his MSH analyzer to PowerShell Analyzer, if you don't know this great PowerTool check out his blog Karl Prosser - Klumsy Geek

I did add the -noBase switch (but it seems not needed that often anymore)

and I did add a -array switch as I made the function also take pipeline input, I did rename it and fixed the Focus issue (for more info search for GUI in the blog), now you can use it like this

out-propertyGrid (get-date)

opg (LS)

opg (ls)[0# shows first file / dir

ls | opg # shows last file (check the date editor ;-)

ls | opg -array # shows list

gwmi win32_operatingsystem | opg # note that you can browse in the Grid !

gwmi win32_share | opg -a

if you have a WMI Object in the PropertyGrid, try to open the properties, you get a nice list. Also try to change a date of a file you get a nice calendar.

the MSHObject (PsObject) was needed in the old beta as otherwise I did get the wrapperObject, so maybe its better to make the shitch called -PsObject and change it to $psObject.PsObject)

here is the Updated script :

# out-PropertyGrid.ps1   
# will show an Object in a PropertyGrid (propertywindow in Visual Studio) 
# this is an easy way to look at MSH objects, you can read / write the object properties.
# /\/\o\/\/ 2006   
# http://mow001.blogspot.com

Function out-PropertyGrid {
  Param ($Object,[switch]$noBase,[Switch]$array)
  $PsObject = $null
  if ($object) {
    $PsObject = $object
     if ($Array.IsPresent) {
       $PsObject = @()
       $input |% {$PsObject += $_}
       $input |% {$PsObject = $_}
  if ($PsObject){
    $form = new-object Windows.Forms.Form 
    $form.Size = new-object Drawing.Size @(600,600
    $PG = new-object Windows.Forms.PropertyGrid 
    $PG.Dock = 'Fill' 
    $form.text = "$psObject" 
    if ($noBase.IsPresent) {"no";
      $PG.selectedobject = $psObject 
      $PG.selectedobject = $psObject.PsObject.baseobject 
if (!(get-command -ea SilentlyContinue opg)) {set-alias opg out-PropertyGrid}


Greetings /\/\o\/\/
Tags :

posted by /\/\o\/\/

Wednesday, April 26, 2006


PowerShell AD site Finder

In this post an example function/script (get-Site) that will find the AD site from a given IPAddress or Hostname.

In this script two nice new features in PowerShell are shown :

byRef Parameters and Switch Parameters.

also you could see I started using new aliases a couple of weeks ago.
I waited a long time using the common % and ? aliases as I keep forgetting them (see new on my blog) but now the fist one its still mine but the others are standard !
so these line are not necessary anymore :

# check needed aliases
if (!(get-command -ea SilentlyContinue new)) {set-alias new New-Object}
if (!(get-command -ea SilentlyContinue %)) {set-alias % ForEach-Object}
if (!(get-command -ea SilentlyContinue ?)) {set-alias ? Where-Object}
if (!(get-command -ea SilentlyContinue gwmi)) {set-alias gwmi get-WMIObject}

and you will see them a lot more ;-)

an other thing to note is that I did split up the function in 2 parts

the function Find-site and the function Get-site.
I do this becouse I like to paste code into the PowerShell Console.

b.t.w. this is also why I always put the { at the end of the line (oposed to on the next line) and why I never use tabs in the examples this is to keep it parsable from the interactive prompt , so that I can paste it. in a script this is not needed, but this keeps the samples easy to try.

if you want to build it in a script, this would be a more common form :

# get-Site.ps1
param ($Computer,[switch]$Verbose)

# Main function
Function Main {}

# helper functions

function FindSiteByIp {}

# Start Main Function

. Main

but to test by pasting them into the commandline when needed, I wil use 2 functions

The first function is the WorkHorse :

it will take a net.ipAddress Object as input, calculate possible Subnets of the IP number and try to find the subnet in AD till it does find one, then it does list the subnet and Site info from AD.

*Note* again for the example I did declare the AD stuff in one place, in a production script you would declare it only once and just set the filter in the loop.
but now with no AD handy its easy to remark the AD part and more readable I think for an example.

the first function does look like this :

# find the AD site from a given IP Number
# Helper Function for Get-Site Function / Script
# /\/\o\/\/ 2006 
# http:/mow001.blogspot.com

Function find-Site {
  param ([net.ipAddress]$ip)

  # Resolve possible NetworkNumbers

  for ($bit = 30 ; $bit -ge 1; $bit--){
    [int]$octet = [math]::Truncate(($bit - 1 ) / 8)
    $net = [byte[]]@()
    for($o=0;$o -le 3;$o++) {
      $ba = $ip.GetAddressBytes()
      if ($o -lt $Octet) {
        $Net += $ba[$o]
      }ELSEIF ($o -eq $octet) {
        $factor = 8 + $Octet * 8 - $bit
        $Divider = [math]::pow(2,$factor)
        $value = $divider * [math]::Truncate($ba[$o] /  $divider)
        $Net += $value
      }ELSE {
        $Net += 0
    $NetWork = [string]::join('.',$net) + "/$bit"

    # try to find Subnet in AD

    if ($verbose.IsPresent) {write-host -fore 'yellow' "Trying : $network"}
    $de = new directoryservices.directoryentry('LDAP://rootDSE')
    $Root = new directoryservices.directoryentry("LDAP://$($de.configurationNamingContext)")
    $ds = new directoryservices.directorySearcher($root)
    $ds.filter = "(CN=$NetWork)"
    $r = $ds.findone()
    # If subnet found, write info and exit script.

    if ($r) {
      write-host -fore 'yellow' "AD Site found for $IP :"

You will see some math to calculate the different network ID's possible.

then it will connect to the RootDSE to get the configurationNamingContext, connects to that with a Directory Searcher to find the subnet.

note also the :


to get from the searchresult to the directoryentry and then to the Site Object.

I will not go into that in this post but search for AD on my blog (top or botom of page) to find more info about PowerShell and AD and for Byte for more info about the Math .

this Math was from an Old VB.NET "script" I made, working from former byte examples, this would be a way also : (I made this to refresh my IP math, from other byte examples) ;-)

# List possible networks for IP number
# /\/\o\/\/ 2006  
# http://mow001.blogspot.com 
function Parse-IP {
 param ($sIp)
 $ip = 0
   $Bytes = $ip.GetAddressBytes()
   for ($bits = 30;$bits -gt 0; $bits--) {
     Switch ([system.Math]::Truncate($bits / 8)){
       3 {
           $script:sum = 0 ; for ($i= (8 - ($bits - 24));$i -le 7;$i++){if ($bytes[3] -band [math]::pow(2,$i)) {$script:sum += ([math]::pow(2,$i))}}
       2 {
           $script:sum = 0 ; for ($i= (8 - ($bits - 16));$i -le 7;$i++){if ($bytes[2] -band [math]::pow(2,$i)) {$script:sum += ([math]::pow(2,$i))}}
       1 {
           $script:sum = 0 ; for ($i= (8 - ($bits - 8));$i -le 7;$i++){if ($bytes[1] -band [math]::pow(2,$i)) {$script:sum += ([math]::pow(2,$i))}}
       0 {
           $script:sum = 0 ; for ($i= (8 - ($bits));$i -le 7;$i++){if ($bytes[0] -band [math]::pow(2,$i)) {$script:sum += ([math]::pow(2,$i))}}

# test Code


this script also shows the usage of the [ref] variable in tryParse()
But on to the Second (not counting parse-IP sample), Script.

this will do 2 things, first it checks if the $computer parameter is an IP Address
by doing a tryParse() , (this method is much nicer to work with as the Parse function, as you canuse it in an IF statement as in the Example.
Before in Monad/MSH this was not yet possible as the [ref] type was not supported yet.) if its not an IP number it will assume it is a hostname and will try to ping it to get the IP adress. (if ICMP is disabled, but you are admin on the remote, you can also consider adding a WMI try also to get the IP address (for more WMI info search for WMI on my blog)

the Second thing you will see is the use of the [switch] parameter, as the boolean behavour is changed (see also release notes)

so the second script is a wrapper to make it more easy to use the find-ip function.

this script looks like this :

# find the AD site from a given IP Number
# Will Find an AD site from an IP Number or a Hostname
# /\/\o\/\/ 2006 
# http://mow001.blogspot.com

Function Get-site {
  param ($Computer,[switch]$Verbose)
  $ip = 0
  if ([net.ipaddress]::tryparse($computer,[ref]$ip)) {
    find-site $ip
    if ($verbose.IsPresent) {write-host -fore 'yellow' "$Computer is No IP Address, trying Ping"}
    $ping = new Net.NetworkInformation.Ping
    &{TRAP{$ip = $null;continue}
      if ($verbose.IsPresent) {write-host -fore 'yellow' "Pinging : $computer"}
      $ip = $ping.send("$Computer").address
      if ($ip) {
        write-host -fore 'yellow' "$computer resolved to $ip";find-site $ip
      }ELSE {
        write-host -fore 'yellow' "$computer Not found"

and the 2 together can be used like this :

Get-site mowPC44
Get-site mowPC44 -verbose

You see in the examples below Used the [switch] to togle verbose mode to output more info (shortened to -V), and in the scripts I use :

if ($verbose.IsPresent) {write-host -fore 'yellow' "text"}

constructions to output the extra info (only to console not to pipeline !).

Usage Examples :

# Get-Site using IP number


AD Site found for :
MOW The Netherlands

# get site using HostName

MowPS>Get-site MowPC44

MowPC44 resolved to
AD Site found for :
MOW The Netherlands

# Using Verbose Mode :

MowPS>Get-site mowPC44 -v

MowPC44 is No IP Address, trying Ping
Pinging : MowPC44
MowPC44 resolved to
Trying :
Trying :
Trying :
Trying :
Trying :
Trying :
Trying :
Trying :
Trying :
Trying :
Trying :
AD Site found for :
MOW The Netherlands

You see that the Wrapper makes a a lot easier, by checking the IP number and the option to use a hostname using ping, I use the Ping version to locate SMS roaming clients, to check DPs.


Greetings /\/\o\/\/
Tags :

posted by /\/\o\/\/

PowerShell and SMS 2003

Yesterday I did read about this MMS session from Jim Bradbury:
LC09 – Automating SMS Tasks with Monad Scripting, here :Day 1 - MMS 2006 - Part 2

Nice to hear he did mention my blog, I did see this session on the agenda of the MMS and did already think it did look interesting, as I just did an SMS 2003 implementation and still I'm busy with it, and I also Used Monad (and still do use PowerShell) a lot with SMS.

So I hope there will be a transcript of this session.

but then I did realize that I only have one SMS example yet on my blog and it's hidden in the CSV series. (it's in part 1),
I made this into a 36 lines select statement (one-liner ;-) to do a Crosstab software report building from the CSV sample using a lot of SMS queries AD and CMDB info that way in PowerShell.
the rest I mostly did prototyping in MSH, but to make it up a bit I post some basic examples here :

basicly I used 3 methods to use SMS with PowerShell,

1) WMI queries like the one in the CSV example.

2) Using the Client COM Objects :

getting available actions (as in controlPanel)

MowPS>$mgr = new -com CPApplet.cpappletmgr

ActionID                      Name                                       DisplayNameResID DisplayNameResDLL
--------                      ----                                       ---------------- -----------------
{00000000-0000-0000-0000-0... MSI Product Source Update ...                         10010 cfg_res.dll
{00000000-0000-0000-0000-0... Hardware Inventory Collect...                         10001 cfg_res.dll
{00000000-0000-0000-0000-0... Discovery Data Collection ...                         10004 cfg_res.dll
{3A88A2F3-0C39-45fa-8959-8... Request & Evaluate User Po...                         10007 cfg_res.dll
{8EF4D77C-8A23-45c8-BEC3-6... Request & Evaluate Machine...                         10008 cfg_res.dll 

and start them :

# Performing a Computer and User Policy Evaluation

$mgr.GetClientActions() |? {$_.name -like 're*'} |% {$_.PerformAction()} 

# You can also use the Object directly, without putting it into a variable first :

# Trigger a Hardware Invertory

(new-object -com CPApplet.cpappletmgr).GetClientActions() |? {$_.name -like 'hardware*'} |% {$_.PerformAction()} 

The triggering of the computer policy is very handy after sending software to the client, as this has to be done remote on the client, in the end I used a Vbscript and PSExec, as I don't have PowerShell deployed yet ;-)
But I did a lot of prototyping in MSH (PS).

3) you can Find a .NET DLL in the SMS SDK you can use to manage SMS :

# Make Managed Connection

$cred = get-credential
$sms = new Microsoft.SystemsManagementServer.Automation.smsprovider("Mowsms001",$cred.username,($cred.GetNetworkCredential().password),"Site_M03")

# list all defined queries

$sms.Queries.get('Y030003A') | fl QueryID,Name,SQLExpression 

# Add some direct rules

$Col = $sms.COLLECTIONS.Get('M03000AE')
$rule = new-object Microsoft.SystemsManagementServer.Automation.SMSCollectionRuleDirect("SMS_R_System",69438,"MowPC44")
$rule = new-object Microsoft.SystemsManagementServer.Automation.SMSCollectionRuleDirect("SMS_R_System",63535,"MowPC23")

You can see, that I can just load the DLL into PowerShell and start using it.
This where just some basic examples, but I hope that this, together with the CSV power of PowerShell (see the CSV series) and working with SMS
I'm sure Jim Bradbury did a better job at this, but I wanted to do a post for the ones that,as me, could not be there and have to hope for a transcript

also you have to watch for big WMI queries in SMS that will take a long time and a lot of memory. (but most SMS admins I think will be used to that)
but in MSH it could stall the pipeline and also stop Ctrl-C from working (ctrl-Break will work but quits the Shell)

See this example :

$oq = new system.management.objectquery
$oq.QueryString = "select * from SMS_CM_RES_COLL_MOW000B6"
$mos = new-object system.management.ManagementObjectSearcher($oq)
$mos.scope.path = "\\SMSServer\root\sms\Site_MOW"

# Streaming (items one-by-one)


# gathering / blocking (Items all at the same time)

$mos.get() | select name,ResourceID
$mos.get() | ft

b.t.w. this is only a collection, hence is still workable, the real
problems begin when I do this with big software queries.

the workaround is this :

MSH>1 | foreach { $mos.Get() } | select name,ResourceID

See also this
:NewsGroup thread (end of the thread)

I could only do a quick post a few examples, as I also was planning an item about some new features in PowerShell As Ref variables and switch-parameters to functions.
but still hope this is useful.

Dont't forget to use Get-Member on the SMS Objects to See whet they can do this helps a lot.

I will do this in an example to get the AD subnet and sitename of an IP adress or a Hostname, I hope to post later this evening .

Greetings /\/\o\/\/

Tags :

posted by /\/\o\/\/

Tuesday, April 25, 2006


Upgrading MSH, My first Windows PowerShell Commands

My first 3 Windows PowerShell Commands

PS G:\MOWSH> $host.version

Major Minor Build Revision
----- ----- ----- --------
1 0 9567 0

# let me run my scripts No Regedit !!

Set-ExecutionPolicy RemoteSigned

Move Profile to Documents and Settings\All Users\Documents\PSConfiguration\Microsoft.PowerShell_profile.ps1

# rename my scripts (otherwise my profile opens with notepad)

ls . *.msh -rec %| {rename-item $_.fullname ($_.name -replace ".msh",".ps1")}

now cleaning up, all the subscript calls in my profile ;-(

and ofcource the CMDlet name changes :

CMDLET RENAME: combine-path -> join-path
CMDLET RENAME: parse-path -> split-path
CMDLET RENAME: match-string -> select-string
CMDLET RENAME: time-expression -> measure-command
CMDLET RENAME: write-object -> write-output
CMDLET RENAME: All *-property cmdlets renamed to *-itemproperty: clear-itemproperty, copy-itemproperty, get-itemproperty, move-itemproperty, new-itemproperty, remove-itemproperty, set-itemproperty
CMDLET RENAME: trace-expression -> trace-command
CMDLET RENAME: invoke-command -> invoke-expression
CMDLET RENAME: Import-SecureString -> ConvertTo-SecureString
CMDLET RENAME: Export-SecureString -> ConvertFrom-SecureSring
CMDLET RENAME: Get-Provider -> Get-PSProvider
CMDLET RENAME: Get-drive -> Get-PSDrive
CMDLET RENAME: New-drive -> New-PSDrive
CMDLET RENAME: Remove-drive -> Remove-PSDrive

even my Custom Typeformatting has to be renamed

hmm, not a fun upgrade becouse of all that renaming, but tomorrow I will show some cool new tricks, and we will forget all those troubles.

b.t.w. a lot of older script on my blog will need a bit of fixing after this,
I will post updated versions of the bigger scripts later on.

gr /\/\o\/\/
Tags :

posted by /\/\o\/\/

Some more Windows PowerShell Links and info.

While we are waiting for the RC Download to appear (could be any minute now) ,

*EDIT* the RC1 Bits are there ! (See links last post)

The first post is in on the new Windows PowerShell Blog about the MMS Keynote,
With this first post the Monad Team blog has moved to this new location.

and I forgot to mention that we will get a Windows PowerShell Portal,
(not live yet but should be at http://www.microsoft.com/powershell )

Also on TG Daily this article about Windows PowerShell ,

And if you download and install the new Bits, do not start regedit to soon ...,

Set-ExecutionPolicy RemoteSigned

... might do the trick ;-)

but on the other hand I think we have some renaming to do the get the old profile and scripts functioning again, as there are a lot of naming changes in the extensions, profile locations and CMDlets.

Hence, if you have a lot of scripts or it will take a bit more time as with last upgrades to get the custom Power back to the Shell again ;-).

and if you run the New bits, try to hit tab after a command and a minus-sign

Eg :

Get-Command -[tab]

Get-Command -Verb

this is a great way to explore the possible arguments of a CMDlet, without the need to use get-help.

this did bring me this :

Get-Command -TotalCount 3

Greetings /\/\o\/\/
Tags :

posted by /\/\o\/\/

Windows PowerShell (Monad / MSH)

The new name of Monad is announced, it is Windows PowerShell.

And more good news from the MMS,
RC1 of Windows PowerShell will be released later today, so watch the download center ;-).

You can use the links below that will point to the latest versions (at the moment 3.1 but as said this will change in a couple of hours (Tip : also check the Docs) :

X86 latest build: http://go.microsoft.com/fwlink/?linkid=64772&clcid=0x409
X64 latest build: http://go.microsoft.com/fwlink/?linkid=64773&clcid=0x409
Documentation: http://go.microsoft.com/fwlink/?linkid=64774&clcid=0x409

Also there will be launced a PowerShell portal on microsoft.com later this week and we will move to our own PowerShell newsgroup ( this will take a month or so ).

In these new RC bits there are a lot of cool improvements as Tab completion on Parameters and ByRef variables.

and also some new names for commandlets, and the extension for an PowerShell script will be .PS1

I will soon post some examples of the new fuctionality on my blog.

Greetings /\/\o\/\/

Tags :

posted by /\/\o\/\/

Tuesday, April 18, 2006


Simple port scanning using Monad

working from the C# example id William Stacey in the Newsgroup, (Monitoring Ports on Remote System ), I made this very simple MSH example.

I did remove the Threading (so if you have a lot of ports, Yes it's slow) but I did add some basic Banner Grabbing.

The script looks like this :

# Scan-Ports.msh  

# Scans computer for a list of ports and tries to get Banners on open ports
# /\/\o\/\/ 2006  
# http://mow001.blogspot.com 

# check needed aliases

if (!(get-command -ea SilentlyContinue new)) {set-alias new New-Object}

# Load Function

Function Scan-Ports {
  param ($server = "localhost",[int[]]$ports)
    trap{"Server $Server not Found";continue}
    $ping = new Net.NetworkInformation.Ping
    $script:result = $null
    $script:result = $ping.send($server)
  if ($result) {
    foreach ($port in $ports) {
      Trap {"$port Not Open";continue}
      "Checking $server $port :"
      $client = new net.sockets.tcpclient
      if ($client.connected) {
        "$port is Open, Trying to get banner"
        $stream = $client.GetStream()
        $chars = @()
        sleep -m 1000 # Give server some time to react 
        while ($stream.DataAvailable) {$chars += [char]$stream.readByte()}

You can Use the script like this :

# Usage :

MSH>Scan-Ports mail 110

Checking mail 110 :
110 is Open, Trying to get banner
+OK InterMail POP3 server ready.

# or for more flexibility :

$server = "mail"
$ports = 21,25,23,80,110,8080,4444 + 130..140
#$ports = @(110)

Scan-Ports $server $ports
<snap> ... <snap>
Checking mail 80 :
80 Not Open
Checking mail 110 :
110 is Open, Trying to get banner
+OK InterMail POP3 server ready.

Checking mail 8080 :
8080 Not Open
Checking mail 8080 :
8080 Not Open
Checking mail 4444 :
4444 Not Open
Checking mail 130 :
130 Not Open
Checking mail 131 :
131 Not Open

<snap> ... <snap>

# or make flexible ranges like this :

scan-ports 'mail' @(21,25,23,80,110,8080,4444 + 130..140)

# I had some problems with the MS telnet server :

MSH>Scan-Ports localhost 23
Checking localhost 23 :
23 is Open, Trying to get banner
ÿû☺ÿû♥ÿy'ÿy▼ÿy ÿû

# should be UTF8 I think but all this did not work :


Note, that I first ping the Computer and only if I get a reply I do a portscan, to speed it up a bit, if ICMP is disabled you should remove this.
Also you can get some speed using Karl Prosser's (very Cool ) start backgroundpipeline snapin : http://www.karlprosser.com/coder/?p=39

and as you can see in last example the MS telnet banner is unreadable.


Greetings /\/\o\/\/

Tags :

posted by /\/\o\/\/

Monday, April 10, 2006


Large AD queries in Monad

Motivated by the following Newsgroup thread about listing a AD query result of more then 1000 Objects.

For gettings objects from AD this is easy fixed by setting just setting a PageSize.
see also Retrieving Large Results Sets [ADSI] on MSDN for more information.

see the following example:

# AD Large queries examples :
# /\/\o\/\/ 2006

# Query a OU with more as 1000 Users :

$strROOT = 'LDAP://OU=Users,dc=Domain,DC=com'
$Root = New-Object DirectoryServices.DirectoryEntry $strROOT
$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = $root

# setting a pagesize will give all Users
if not the max is 1000 (Default) or as set in AD

# $searcher.PageSize = 900

$searchItem = "CN"
$searchValue = "*"
$searchClass = "User"
$SearchCat = "*"
$searcher.Filter = "(&($($searchItem)=$($searchValue))(objectClass=$($searchClass))(objectCategory=$($SearchCat)))"

$PropList = "CN","ObjectClass","ObjectCategory","distinguishedName","lastLogonTimestamp","description","department","displayname"
$PropList | foreach {[void]$searcher.PropertiesToLoad.Add($_)}

## Examples :

# without pageSize set :

MSH>$searcher.findAll() | measure-object

Count    : 1000

# with pageSize set ( remove # before the $searcher.pagesize = 900)

MSH>$searcher.findAll() | measure-object

Count    : 2629

Not that bad is it ?,

but now the following, how about getting the members of a large AD group.
The Members property will only list 1500 Objects at Maximum.

As you can see, here you have to do a "Base" search using the directorySearcher on the DirectoryEntry you want to get te members of.

also you need to do the Paging yourself in this situation.

As this is not as easy as paging the Query, I worked out this quick example how to do this from MSH :

# AD Large Members listing example :
# /\/\o\/\/ 2006

# list members of a group with more as 1500 Users :

# getting members the normal way (1500 max) :

$group = new DirectoryServices.directoryEntry('LDAP://CN=Group,OU=Groups,dc=Domain,DC=com')

MSH>$group.member | measure-object

Count    : 1500

# Getting Members Paged

$group = new DirectoryServices.directoryEntry('LDAP://CN=Group,OU=Groups,dc=Domain,DC=com')

$from = 0
$all = $false
$members = @()
while (! $all) { 
  trap{$script:all = $True;continue}
  $to = $from + 999
  $DS = New-Object DirectoryServices.DirectorySearcher($Group,"(objectClass=*)","member;range=$from-$to",'Base')
  $members += $ds.findall() | foreach {$_.properties | foreach {$_.item($_.PropertyNames -like 'member;*')}}
  $from += 1000

# now the count is correct :

MSH> $members | measure-object

Count    : 2621

You can see this is a bit more work as we have to do the paging ourselves.
Also the first time I did run into this it has cost me some time to figure this out (while I already was aware of the "normal" paging).

So I hope this will help if you come to this situation yourself.

Greetings /\/\o\/\/
Tags :

posted by /\/\o\/\/

Sunday, April 09, 2006


Sharepoint provider for Monad

In my last post about the MSH Community Workspace,

I did already see Oisin Grehan's name on the list, and did remember his Sharepoint provider,

but could not find it at the time, as he posted an update to the provider also to the workspace, here are the links :

Msh / Monad Provider for SharePoint 0.4 Source
...released to GotDotNet's MSH Community Extensions

and here the link to the Monad feed on his sharepoint blog.

To bad this is another provider I cannot test at the time, but it's great to see another provider being born, and for the Sharepoint guys, be sure to check this one out ;-)

gr /\/\o\/\/

Tags :

posted by /\/\o\/\/

Saturday, April 08, 2006


access ADSI WinNT provider from Monad Part 2

In my first post about accessing the WinNt provider from MSH, MSH access NT provider I used an ugly workaround using inline VB.NET code.

I found a better solution (inspired by James truher's get-lastlogon example on MonadSource)

This one first loads the microsoft.visualbasic namespace,
then uses the GetObject method of the microsoft.visualbasic.interaction class to get the Com-Object.

after that I will use the InvokeMember Method on the type, using Reflection binding flags to call the method or Property.

# Get-Admins.msh 
# gets the users in the admininstrators group
# using Visualbasic namespace, reflection and the WinNT provider
# /\/\o\/\/ 2006 
# http://mow001.blogspot.com 


$Group = [microsoft.visualbasic.interaction]::GetObject("WinNT://./administrators,group",$null)
$GroupType = $Group.gettype()

$im = [reflection.bindingflags]::InvokeMethod
$gp = [reflection.bindingflags]::GetProperty
"Members :";""
$members = $GroupType.invokemember("members",$im,$null,$Group,$null)
$members | foreach  {
  $userType = $_.gettype()
  $userType.invokemember("name",$gp,$null,$_ ,$null)
  $userType.invokemember("AdsPath",$gp,$null,$_ ,$null)

It's still a bit "Hacked" way to do this, but I think it's much better as the VB.NET one ;-)

This makes it realy possible to make much better use of the WinNT provider from MSH
We are still "working in the Dark", as we can not use GM, but You can use the ADSI WinNT Provider doc's in the SDK on MSDN to get help on the properties and methods.


Greetings /\/\o\/\/

Tags :

posted by /\/\o\/\/

Friday, April 07, 2006


MSH Community Workspace, TFSC provider and videos

I did read on Lee Holmes blogd that Monad Team Foundation Source Control Provider Now Available, (by James Manning) on MSH Community Workspace from Keith Hill .

I'm not a programmer so not using it, but if you are be sure to check it out, I'm told it's Cool ;-)

also while searching for a link to the Channel 9 videos, I could not find them all,
so here they are all, if you have not seen them be sure to check them out !!

Monad videos on Channel 9

Jeffrey Snover - More talking about Monad

Jeffrey Snover - Monad demonstrated

Jeffrey Snover - Monad explained

also I will add some new links to the $links array (on the bottom of the page)most mentioned before but for reference
Monad videos on Channel 9
MSH Community Workspace

and correct the links to the online documentation :

Monad GettingStarted guide
Monad Progamming Guide
Monad SDK


gr /\/\o\/\/

Tags :

posted by /\/\o\/\/

Monday, April 03, 2006


more Monad scripts, and a bit more CSV

more and more sample scripts for Monad are posted,

On scripts.readify.net under scripts 5 scripts are added this week, you can get 12 examples there now, and the number seems to grow fast, they also have a RRS feed so you can get notified when new scripts are added , I'm subscribed !.

In the last script in the script session , "Read Records from a Database" you can see how te read the data from the connection without putting it in a dataset first and work with it ofline, as I mostly do see last 2 post (" working with CSV files in MSH (part two) "," working with CSV files in MSH (part one) and the links to connecting other datasources in part 1, you can use this method with all conections mentioned.

if you only want to looponce trough the records this is not so resource intensive (E.g. do something for each record in a CSV file), then using just a reader,
as I wil show in the examples below.
if you only need the first field of the first record found a executeScalar is even faster.

Also on www.monadsource.com in Downloads new Scripts are added, some of them are from my blog, e.g. Remote Desktop Management, Cluster Watch, WMI Data Grid , and some more (not all links are working yet at the moment, but I'm sure this get fixed) , but scripts from all kind of sources are added here, making it more handy to get to the script.

Examples :

function new-DbCommand { 
  Param ($strCmd ) 
  $cmd = new-object System.Data.OleDb.OleDbCommand($strCmd,$Conn) 
  return $cmd

MSH>$AdComputers = new-DbCommand "Select * from ADComputers#csv"
MSH>$computers = $adcomputers.ExecuteReader()

# get the names of the tables


# now we first need to read

Unable to index into an object of type System.Data.OleDb.OleDbDataReader.
At line:1 char:12
+ $computers[0 <<<< ]


# now this works

10/17/2005 11:02:32 AM

#read next record


# for a real quick way (just to check a computer is there this reurns only the first field of the first record):

MSH>(new-DbCommand "Select name from [ADComputers#csv] where name = 'PC41'").executescalar()
MSH>(new-DbCommand "Select name from [ADComputers#csv] where name = 'PC42'").executescalar()

*edit* commented this also, but think this deserves an edit, don't forget the MSH "shortcuts" to arrays(enums) can be used here also

10/17/2005 11:02:32 AM

MSH>$computers[0..($computers.fieldcount - 1)]
10/17/2005 11:02:32 AM

10/17/2005 11:02:32 AM

You can see from the interactive examples above, and the SQL script from scripts.readify.net that does a loop (as you did see in the examples above this works also for a CSV, Excel of Access ADO connection), that this is a great way to use those connections to make action upon .(I'm sure I will show it a later example on my blog)


Greetings /\/\o\/\/
Tags :

posted by /\/\o\/\/


October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   April 2006   May 2006   June 2006   July 2006   August 2006   September 2006   October 2006   November 2006   December 2006  

$Links = ("PowerShell RC1 Docs"," PowerShell RC1 X86"," PowerShell RC1 X64"," Monad GettingStarted guide"," Monad Progamming Guide"," Monad SDK"," Monad videos on Channel 9"," MSH Community Workspace"," scripts.readify.net "," MonadSource"," www.reskit.net"," PowerShell Blog"," Under The Stairs"," computerperformance powershell Home"," proudlyserving"," MSH on wikipedia"," MSHWiki Channel 9"," Keith Hill's Blog"," Precision Computing"," PowerShell for fun"," MSH Memo (Japanese)"," monadblog")

find-blog -about "PowerShell","Monad" | out-Technorati.
find-blog -contains "","" | out-Technorati.
Web mow001.blogspot.com

This page is powered by Blogger. Isn't yours?