/\/\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 "," ")

Thursday, June 29, 2006


PowerShell and MOM 2005

Microsoft Operations Manager 2007(MOM2007), will be build on powershell, so there will be Cmdlets to manage MOM2007 and everything you can do in the GUI you can do in PowerShell.As I'm Implementing a MOM2005 environment as MOM2007 is still in Beta.
So we have to miss the MOM Management Shell (Snap-In) and all those nice Cmdlets as shown at TechEd .

But then again........ Maybe not .

As I had a very good experience with using a .NET DLL from the SMS 2003 SDK (Microsoft.SystemsManagementServer.Automation.dll) See : PowerShell and SMS 2003

I Downloaded the MOM SDK, but no DLL so did look at the .NET examples in the SDK ,
and what seems to be the Case the are allready there, under the MOM programs directory is allready a SDK bin directory, from the examples I did learn that you needed 2 DLL's : Microsoft.Mom.Sdk.dll and mom.context.dll , on My Workstation I could only find Microsoft.Mom.Sdk.dll , but on the MOM ManagementServer the latter was also there, I tried copying it to my client but that did not work, So I installed PowerShell on the Server (As I was lucky that it is our server not the customers I was able to do that) .

And as the DLL's are allready there I needed only this 3 "Magic Lines" and my MOM2005 Management Server was "PowerShell Enabled".

# PowerShell Enable MOM2005
# /\/\o\/\/ 2006
# (works only on MOM managentserver)

# Load Needed DLL's (default Installed)

[System.Reflection.Assembly]::LoadFile("$($env:ProgramFiles)\Microsoft Operations Manager 2005\SDK Bin\Microsoft.Mom.Sdk.dll")
[System.Reflection.Assembly]::LoadFile("$($env:ProgramFiles)C:\Program Files\Microsoft Operations Manager 2005\SDK Bin\mom.context.dll")

# Get a Mom Administration Object

$mom = [Microsoft.EnterpriseManagement.Mom.Administration]::GetAdministrationObject()

# And we are Ready to Go : 

# Ask the Object what we can do With it :

$mom | gm

# get groups and puters

$mom.GetComputerGroups() | ft name,ComputerIncludeList

#get agents and states :

$mom.GetAgentManagedComputers() | FT Name,State

# get rulegroups


From here on as you also can see in the Acive Directory series I currently running,
its easy to learn from the Object itself using Get-Member (see example above when you run it) and to construct easy Functions to mimic the MOM2007 CDMlets.
e.g. :

PoSH>$mom.GetAgentManagedComputers() | FT NAME,STATE

Name                           State
----                           -----
MS001                          Error
MS002                          Error
MS012                        Warning
MS046                        Success
MS047                        Success
MS048                        Success

# Make it a Function :

Function get-MomAgentManagedComputers {
    $mom.GetAgentManagedComputers() | FT NAME,STATE

Or as is almost just as easy for most task just just the variable and create (Sub) variables ;-)

# Get RuleGroups

PoSH> $mom.GetRuleGroups()

ID         Name                          Description                             Enabled
--         ----                          -----------                             -------
8fff-00... Dell OpenManage               Processing rule group for ...              True
b050-31... Microsoft Baseline Securit... Microsoft Baseline Securit...              True
976a-ca... Microsoft Operations Manager                                             True
afa4-50... Microsoft Operations Manag... Checks that installed MP v...              True
a7af-00... Microsoft SQL Server          Container for rules to mon...              True
87ec-00... Microsoft Windows Internet... Container for rules to mon...              True
be95-91... Microsoft Windows Print Se... Microsoft Windows Print Se...              True
bb02-42... Microsoft Windows Server 2... Container for rules to mon...              True
8b4c-ca... Microsoft Windows Server C... Microsoft Windows Server C...              True
8803-00... Microsoft Windows Servers ... Microsoft Windows Servers ...              True

# Look at the overloads :

PoSH> $mom.GetRuleGroup

MemberType          : Method
OverloadDefinitions : {Microsoft.EnterpriseManagement.Mom.RuleGroup GetRuleGroup(Guid ruleGroupId)}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : Microsoft.EnterpriseManagement.Mom.RuleGroup GetRuleGroup(Guid ruleGroupId)
Name                : GetRuleGroup
IsInstance          : True

# OK we Need the give the ID :

PoSH> $dell = $mom.GetRuleGroup('00371cb6fed7')
PoSH> $dell

Id                            Name                          Description                      Enabled
--                            ----                          -----------                      -------
8fff-00... Dell OpenManage               Processing rule group for ...                          True

# and a "$dell | get-member" did learn us that we could do this :

PoSH> $dell.GetSubRuleGroups()

Id         Name                          Description                                         Enabled
--         ----                          -----------                                         -------
9b9d-32... State Monitoring and Servi... Rules for Dell state monit...                          True
98e4-4a... Array Manager                 Processing rules for Dell ...                          True
af8e-57... Discovery                     Discovery of Dell Computers                            True
b914-68... Management Servers            Dell Management Pack Rules...                          True
9613-87... Server Administrator          Processing rules for Serve...                          True
8573-af... Storage Management            Processing rules for Dell ...                          True

# and so on :

PoSH> $DellStor.GetRules() | ft name,Enabled

Name                                                                         Enabled
----                                                                         -------
Dell_OM_SM Device is missing                                                    True
Dell_OM_SM Virtual disk initialization failed                                   True
Dell_OM_SM Predictive Failure reported                                          True
Dell_OM_SM Enclosure power supply has an DC failure                             True
Dell_OM_SM Enclosure firmware mismatch   

PoSH> $DellStor.GetRules()[0]

Id                     : 05073db6ddca
Name                   : Dell_OM_SM Device is missing
Enabled                : True
EnabledOverride        :
AppliedEnabledOverride :
Scripts                : {DellOMSALaunch, Dell RAC Console Launch}
RuleThreshold          : 

# And use the PowerShell Formatting tricks :

# a quick and dirty list of all the computers in the ComputerGroups 

$mom.GetComputerGroups() | select name,@{e={$_.ComputerIncludeList |% {"`n$_"}};n='Computers'} | fl

$mom.GetComputerGroups() | select name,@{e={$_.ComputerIncludeList |% {"`n$_"}};n='Computers'} | fl | Out-Printer

This one of the think I love most in MSH and why it is so great,
- find a SDK,
- look for the .NET DLL's
- load them in the Shell,
- get an .NET Object
- ask what it can do ..
- and of you go .... You can start exploring and learning on the Job.

And again... we don't have to wait for the next version (MOM or PoSH),
we can make a headstart.

If there is someone that knows a way to do this on the client (getting a mom.context.dll that works on the client I think is needed) that would be realy great, so if any MOM guru is reading this, and knows how to do this, please leave a comment.


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


Monday, June 26, 2006


PowerShell and Active Directory Part 2

In this second part of the PowerShell and Active Directory series, we go on from PowerShel and Active Directory Part 1 (Sorry for the Typo)
A quick refresh and commands needed to get back in that state :

# Connect to a Domain (Default Naming Context) :

$root = New-Object System.DirectoryServices.DirectoryEntry

# listing the Child Objects


# Getting a Child Object

$mowOU = $root.get_Children().find('ou=mowOu')

# connect directly to a Active Directory Object using a path

$mowOu = New-Object DirectoryServices.DirectoryEntry("LDAP://OU=MowOu,DC=mow,DC=local")

Also we did see that we can use format-list * / format-Table * to list all the properties,
and that we can get the members and Properties by using get-member.
also you could see that the DirectoryEntry Object is a Wrapper that can contain different kinds of AD Objects, e.g. : Domain,OU,User (and if you did follow my advice and did some "browsing" on your own you could see that that goes also for Groups and other objects). We learned that its always good to check the type of the object that we get back as sometimes it's a bit different that that we expect, also we did see how to use get-member to get the methods of an object that is enumerable.

In this second part we are going to create a user.
and then create a 100 of them and set some more properties.

as in this part of the series we going to write to the ActiveDirectory it might not be a good Idea to do it in a Production environment, or you might not have an AD present and still want to follow the series, for the Demo I did use a VM with a domain controller but you can also use ADAM (AD application Mode) that you can install on your own workstation to test.

For more information about using adam and how to get and install it see this post : (link to Adam still works and looks updated to SP1)
Monad and Adam (and a preview of my to-be AD provider)

(PS nope I did not work on the AD provider anymore and it might take a while before I do, Sorry not enough insomnia time)

also you can find an example to create the MowOU in that post, from there on you can follow the series, only the "automatic" connection to the Domain will not work, you need to give the LDAP path in the DirectoryEntry Constructor, as explained that post.

So after you connected to the Test OU of your choice, let's go on Creating a User

As we have see in former post, the Get_Children() Method of Returns a DirectoryEntries Object, and as I hinted or you might have see in the get-member output this Object also has a Add Method, let's find out how that does work :




MemberType          : Method
OverloadDefinitions : {System.DirectoryServices.DirectoryEntry Add(String name, String schemaClassName)}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : System.DirectoryServices.DirectoryEntry Add(String name, String schemaClassName)
Name                : Add
IsInstance          : True

You call a method in PowerShell with () behind it, if you leave them away as I did above you get some info about the Method,
especially the OverloadDefinitions is very valuable, in this case it shows us that the Add method has one overload and it takes a string name and a string SchemaClassName.

# Create User

PoSH>$user = $mowou.get_Children().add("CN=Mow2",'User')




Exception calling "Find" with "1" argument(s): "There is no such object on the server. (Exception from HRESULT: 0x80072030)"
At line:1 char:27
+ $mowou.get_Children().find( <<<< "CN=Mow2")

# Save






Note that it absolutely needed that you use a variable here as the User Will not be created until you call the CommitChanges Method, you can see that from the first output that the DN name is not yet filled, and if you throw it to the pipeline you can not call the commintChanges() Method, that why you need the variable for this.
OK, OK not completely you can do it also like this ;-) :

# Make an OU 



For the example above you can let PowerShell first evaluate what is in the parents and then call a method on it, also you can see how to do the same for an OU.

OK, Let's do not one user (as they still can say they do it quicker in the MMC GUI, and to have some users to test on in later parts of this series), let's do a 100 (for readability I did 5 here on the blog)and name them MowTest001 to MowTest100 and do not use a script but just go on from the commandline.

first lets count to 100, in PowerShell we have a nice range-operator ".." for this :


Then we can use a pipeline and Foreach (by alias %) :

PoSH>1..5 |% {$_}

and then use a string and and the -F (format) operator in PowerShell, to format the numbers with trailing zeros and add them to a string, first the {0} inserts the first parameter, and then you can also use the .NET formatstrings to format them.

Jeffrey Snover did also a BlogEntry about it on the PowerShell here :
Using Format Control Strings.

For another example (formating as Percent) and some more formatting tricks in PowerShell see this post.

2006 Winter Scripting Games (part 2)

And here (as mentioned in that post also) you can find a good reference for formattingStrings in .NET :
(This is a different one from the one in Jeffrey Snovers's post with some more info !)
Standard Numeric Format Strings

I had some problems with this in the Demo (I turned string and parameter arround) so it might have not been that clear
in the Demo, on the other hand it shows how you can play with a line till you have it right by using the up arrow.( and it was cool for a time to call out : Jeffrey Help ! and he DOES show up to help me out LOL ;-))

# First insert the Number :

PoSH>1..5 |% {"MowTest{0}" -f $_}

# Format Number 

PoSH>1..5 |% {"MowTest{0:d3}" -f $_}

then if you get it right you can make a loop and use the History of your commandsettings to add former commands to the loop, it might be a bit hard to show on paper but the trick was to open the loop, and walk back with the up arrow in you history, edit add former commands you did to the loop, then close it with }[enter][enter] (you need a blank line after it).

# if you add another foreach and curly braces open and press enter you get a >> Prompt

PoSH>1..5 |% {"MowTest{0:d3}" -f $_} |% {

# Walk with upArrow to former line :

PoSH>1..5 |% {"MowTest{0:d3}" -f $_} |% {
>> $user = $mowou.get_Children().add("CN=Mow2",'User')

# Change it, and use DownArrow to walk to the CommitChangesline from history.

PoSH>1..5 |% {"MowTest{0:d3}" -f $_} |% {
>> $user = $mowou.get_Children().add("CN=$_",'User')
>> $user.CommitChanges()
>> }

# Now the items are created.



B.T.W. if you where at the demo from this output you can get what went wrong the first time trying to create them :
I made the first user like this :

$user = $mowou.get_Children().add('CN=Mow2','User')

working correct at the time, but not when I did change it to $mowou.get_Children().add('CN=$_','User') in the loop.

What went wrong ?

As we did create 100 Users, but there is a bit more work to be done (filling properties and Enable them for example),
I will get on to that in the next post, and to format and list the created objects, also You might have noticed the examples in the Adam post where a bit different, I will explain why also in the next post, after that we will look at taking import for SQL or CSV for example and searching AD.


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

posted by /\/\o\/\/

Friday, June 23, 2006


PowerShel and Active Directory Part 1

In my 200th post already (as I did just see) as promised here the start of the Active Directory Management series.

In this first Part I will show how to make a Active Directory Object in Powershell,
connect to a domain, list Properties and Methods of the Object, and how to get the child Objects and store them in a Variable again.We will do all of this interactive from the commandline,

there are no CMDlets yet for Active directory management in PowerShell for version 1,
but as we can use .NET objects from powershell we are still able to manage Activedirectory from Powershell.

the .NET Classes we need are in the namespace system.directoryservices..
(This naming is because as you can connect not only to AD but to an other directoryservices using LDAP as well. )
in .net 2.0 we also have a activedirectory namespace for infrastructure management but more about that later in the Series.

The object we are going to use for this is called a Directoryentry.

So let's start by making a connection to Active Directory. by creating an DirectoryEntry object,
as you might have seen before, to get a .NET object we need the command new-object :

*Warning* As you have RC2 Installed all my AD posts will not work anymore, it is verry confusing, but fixable if you read explaination here PowerShell RC2 and Active Directory :

As I did switch back on all my work PC's (I did call all my colleagues not to upgrade as all our AD tools are messed up, I will not update them, as I would not recommend to upgrade to RC2 of you work with AD a lot.

PoSH> New-Object System.DirectoryServices.DirectoryEntry


and as you can see as a result we get back the distinguishedName of the domain,

there are 2 things to note here,

you can see that the directoryentry constructed without parameters defaults to the default naming context, that is the current domain, in this case mow.local .

second thing to note is that as we just throw the object to the pipeline, so it gets the default formatting and after that its gone.

as I want to use it a bit more, I will put it into a variable so we can keep using it. I just use the arrow-up to get the previous line again, and Home to get to the beginning of the line and type '[variablename] = '. in front of it.
I like to work this way to first check if I get back the object, and then if it is OK I put it into a variable, otherwise I need to check the variable everytime to see if the command succeeded.

as this is connecting us to the root namespace of the domain, I will call the variable $root.

PoSH>$root = New-Object System.DirectoryServices.DirectoryEntry


You can see we now have the Object in a Variable and can start using it

next, as the default formatter only displays the distinguishedName of the directoryentry object.

I use Format-List * ( by the Alias FL )to show all properties.

# Get all Properties 

$root | fl *

you can also get the Methods and Properties of the Object by Using Get-Member :
so next lets ask the directoryEntry Object what more it can do :

# Get All Members 

$root  | get-Member

# Or to get only the Methods :

PoSH> $root | get-member -MemberType method

   TypeName: System.DirectoryServices.DirectoryEntry

Name                      MemberType Definition                                                                       
----                      ---------- ----------                                                                       
add_Disposed              Method     System.Void add_Disposed(EventHandler value)                                     
Close                     Method     System.Void Close()                                                              
CommitChanges             Method     System.Void CommitChanges()                                                      
CopyTo                    Method     System.DirectoryServices.DirectoryEntry CopyTo(DirectoryEntry newParent), Syste...
CreateObjRef              Method     System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)                  
DeleteTree                Method     System.Void DeleteTree()                                                         
Dispose                   Method     System.Void Dispose()                                                            
Equals                    Method     System.Boolean Equals(Object obj)                                                
get_AuthenticationType    Method     System.DirectoryServices.AuthenticationTypes get_AuthenticationType()            
get_Children              Method     System.DirectoryServices.DirectoryEntries get_Children() 

and hmmm, this get_children method looks handy,
let's try : $root.get_Children()

PoSH> $root.get_Children()

{OU=Domain Controllers,DC=mow,DC=local}                                                                               
{CN=NTDS Quotas,DC=mow,DC=local}                                                                                      
{CN=Program Data,DC=mow,DC=local}                                                                                     

Nice just what I needed as there is not much to do in the root of the ActiveDirectory, so lets look if we can connect to one of the SubOU's
You would expext that you can just use the indexer to get to the wanted OU from the Array returned like this :

PoSH> $root.get_Children()[6]
Unable to index into an object of type System.DirectoryServices.DirectoryEntries.
At line:1 char:22

This does not work, you can see the reason for this in the Errormessage,
we did not get back a collection of DirectoryEntry Objects, but one instance of another .NET class : System.DirectoryServices.DirectoryEntries
You can also check on this by asking it for it's type :

# Check the type 


Note that normaly GM (Get_member) will not show this as it does enumerate the Object ( ?? and you just said that it was not a collection.. nope it is not and it has no indexer but it has a GetEnumerator() Method, so the pipeline of PowerShell does Enumerate on it, and get-member will show the members of the Items that got enumerated, but will show them only one for every type thrown to the pipeline)

PoSH> $root.get_Children() | gm

   TypeName: System.DirectoryServices.DirectoryEntry

Name                      MemberType Definition                                                                       
----                      ---------- ----------                                                                       
add_Disposed              Method     System.Void add_Disposed(EventHandler value)                                     
Close                     Method     System.Void Close()                                                              
CommitChanges             Method     System.Void CommitChanges()

you can also give the object as a parameter to get-member to avoid this
Get-Member -inputObject $root

or a workaround I like is put a comma before the object (again as I can use "Arrow Up" to get the last line this change is much easier in interactive use when you need members of the collection not the instances):

,$root.get_Children() | gm

   TypeName: System.DirectoryServices.DirectoryEntries

Name             MemberType Definition                                                                                
----             ---------- ----------                                                                                
Add              Method     System.DirectoryServices.DirectoryEntry Add(String name, String schemaClassName)          
Equals           Method     System.Boolean Equals(Object obj)                                                         
Find             Method     System.DirectoryServices.DirectoryEntry Find(String name), System.DirectoryServices.Dire...
get_SchemaFilter Method     System.DirectoryServices.SchemaNameCollection get_SchemaFilter()                          
GetEnumerator    Method     System.Collections.IEnumerator GetEnumerator()                                            
GetHashCode      Method     System.Int32 GetHashCode()                                                                
GetType          Method     System.Type GetType()                                                                     
Remove           Method     System.Void Remove(DirectoryEntry entry)                                                  
ToString         Method     System.String ToString()                                                                  
SchemaFilter     Property   System.DirectoryServices.SchemaNameCollection SchemaFilter {get;} 

Now we can see its not an array, but we can workaround this lack of an by explicitly making it an array by casting it like this :



but as you also might have seen in the get-member output, the directoryentries class also has a find method, that has a name as a parameter and.
that will find and return a specific child



# and store in a variable again for later usage

$mowOU = $root.get_Children().find('ou=mowOu')

# and list all properties again.

Posh> $MowOu | fl *

objectClass          : {top, organizationalUnit}
ou                   : {MowOu}
distinguishedName    : {OU=MowOu,DC=mow,DC=local}
instanceType         : {4}
whenCreated          : {5/18/2006 7:15:13 PM}
whenChanged          : {5/18/2006 7:15:13 PM}
uSNCreated           : {System.__ComObject}
uSNChanged           : {System.__ComObject}
name                 : {MowOu}
objectGUID           : {139 153 183 252 115 3 24 73 145 12 14 36 64 30 237 202}
objectCategory       : {CN=Organizational-Unit,CN=Schema,CN=Configuration,DC=mow,DC=local}
nTSecurityDescriptor : {System.__ComObject}

note that this is also a DirectoryEntry Object but it will have other properties as it as a OU Object not the domain.

and from here we can use the some method to list the objects (Users / Computers / Sub-OU's)


# and for example get a user into a variable to edit it etc :

$mow = $mowou.get_children().find('cn=mow')

note that this is not the only way to get to the sub-OU, If you know the LDAP Path you can pass it in the constructor and connect to the OU directly :
(also note that you can leave away the system namespace as PowerShell will append it)

# connect directly to an LDAP path :

$mowOu = New-Object DirectoryServices.DirectoryEntry("LDAP://OU=MowOu,DC=mow,DC=local")

In the next part of this series we will create a User, and see how to create a loop to make more as 1 user at a time,
and fill some more properties.

later in this series we will use the DirectorySearcher to do searches in AD

But for now by creating one .NET Object and only the 3 most basic PowerShell Cmdlets (new-object / format-(List/Table) / get-member ) we already can :

Connect to AD
List properties of AD Objects
List methods of AD Objects
Walk to the Domain structure to wanted OU
Connect directly to SubOU's
List members of OU's

and the only thing we have to remember is that we need a directoryServices.DirectoryEntry Object.
It will find out the domain / LDAP path for us if we do not know it, and we can use get-member to remember / learn us what the object can do.and to explore the objects we get back.

So as you see it is not as hard as i might seem being without Cmdlets.

More in next post, till then try walking to different parts of AD this way and look at Computer / Users Objects,and do Format-List * and get-Member on the returned objects, to get used to the DirectoryObject and learn for the output you get back,
(for a preview of the next part Creating a user as in the Demo, note the Add() method on the directoryEntries class)
Feel free to leave remarks or questions in the remarks.


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

posted by /\/\o\/\/

TechEd RoundUp

I had a great TechEd.

First of course having the chance to meet Jeffrey Snover, the Windows PowerShell Architect was realy great and when we did also meet and spend some quality time (a couple of hours on a table with 3 open laptops exchanging a lot of info ;-) ) with Scott Hanselman on Sunday,
after that in the evening the tech-check for the , and then dinner with Jeffrey in Boston.

my TechEd was allready made !

Then on monday, before the Windows PowerShell: Solving Management Problems session I did meet Don Jones who anounced PowerShell support in PrimalScript 4.1 in this session . and that is writing the book Windows PowerShell: TFM, you also you can find 2 interviews he did with Jeffrey Snover Here .
And I also did a Small demo about ActiveDirectory management on stage.
Tomorrow I will post the contents a bit more information about that in the first entry in a series about this as I decided to turn it into a series on the blog to cover a lot more AD stuff.

Also Jeffrey Snover's Tuesday morning session Windows PowerShell: Next Generation Command Line Scripting was great. and I did hear find a lot of good credits about it at TechEd, and in my PowerShell news collector after I got home ( there where a lot of powershell posts last weeks check also DontBotherMeWithSpam 's excellent powershell Links collection he keeps here : http://del.icio.us/powershell )

Scott Hanselmann also did 2 Lighting sessions about powerShell, I did see one of them it was realy great.

Vivek Sharma's Microsoft Exchange Server 2007: Management Shell and Scripting session
was also very good (made seriously considering getting into Exchange again I didn't used since 5.5 and (never did regret) and what would be homework as I have no exchange at work ). the Mark Russinovich sessions where also great, the MOM 2007 PowerShell support. I did see some virtual machine management CMDlets for PowerShell (a hot topic at the moment). Some IronPhyton and RUBY (maybe some more about that in a later post) and much, much more interesting info.

Also I realy enjoyed the talks and powershell demoing between my sessions at the PowerShell Booth, snd all the People I had the chance to meet .

and ofcourse The Train Concert at Fenway park, and The Influencers party where amazing (I had to miss a cruise with Sapien that they where so kind to invite me for and I hid hear was also great ) ,

Tomorrow I will Start a series about Active directory management from PowerShell that will cover the demo material :

- How to use the .NET classes
- Connect to AD
- List SubOU's
- Create a User
- make a loop Create 100 Users
(do some formatting and what went wrong ;-))

but with more background info.

and then going on from that in the followup parts (amongs others).

- filling more properties,
- enabling the accounts.
- connect to the schema to lost possible properties
- using a directorySearcher to search AD
- Large queries / group listings
- Working with logondates
- creating users from CSV
- using activedirectory .NET classes to manage infrastructure.
- making some small utility scripts

I will try to work from the very beginning and from there on to the more advanced sample scripts on my blog and how they work in a 5 - 10 parts series.

also I might change my blog hosting and the layout (after a lot of elbows from Scott Hanselmann on TechEd) so I can also make my blog more accessible, but this can take some time, more about this later.

I did Enjoy,

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

posted by /\/\o\/\/

Thursday, June 22, 2006


A big hurray for the Scripting Guy !

A big hurray for the Scripting Guy !
as Hey, Scripting Guy! Turns 500

and what do you do with you 500th Hey Scripting Guy ??
Answer your first powershell Question ! !

How Can I Use Windows PowerShell to Start a Service on a Remote Computer?

and there is a whole new bunch of Taskbased PowerShell examples also.

What Can I Do With Windows PowerShell?

All for us ungrateful scoundrels, making fun about him, and posting nasy comments about the
Windows PowerShell Script Repository and the scripts in there.

And did him that much pain See : PowerShell's Script Center problem

and still when he turns 500 he thinks first about us !

so let all powershell users send him 2 or more cards ( and Yes !...... snail-mail !! )

and lets promise not to be ungratefull again to the guy that did tell as all (or almost) we know ..

We're not worthy , we're not worthy .. but still forgiven..

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

PS I will start a series about AD and some comments about TechEd later, but this HAD to go first.

posted by /\/\o\/\/

Wednesday, June 14, 2006



A quick post from teched Boston,

for the ones that did see the Powershell session on Monday.
thanks for the positive reactions and I will post a transcript of the AD demo in the beginning of next week. (as I do not have *doink* an electronic version handy.) and blogger did "eat"my first try of posting it (together with the bad wireless connections, so I use a public PC for this post).

till then you can find the tabcompletion Jeffrey and I did use in my last post here :

PowerShell Tab Completion Part 4

and you can find some former AD examples here :

working with CSV files in MSH (part one)
get AD user allowed Logonhours from MSH
AD Infastructure exploring with MSH

MSH AD querying with .NET 2.0 framework
Large AD queries in Monad

PowerShell AD site Finder

Also you can find me around the Powershell stand in the technical education section,
between the sessions I go to, to answer questions or demo some PowerShell stuff.

Greetings /\/\o\/\/

posted by /\/\o\/\/

Thursday, June 08, 2006


PowerShell Tab Completion Part 4

I made another addition to the Tab Completion handeling of PowerShell, multilevel Variable completion.

*Edit* There are newer versions of this script, you can find the
latest on my new blog :
The PowerShell Guy ( http://ThePowerShellGuy.com

This versions are much more powerfull

Just download the latest PowerTab.ZIP file from the overview page
here :
run PowetTabSetup.Ps1 and you are ready to go

I made this addition as the standard tabcompletion, does only expand methods and properties on the first level, and on hitting [tab] the what I did find very annoying.


$host.U [tab]

$host.UI.R [Tab]

$host.UI.RawUI.f [Tab]

with the new tabexpansion function :

$Host.UI.Ra [tab]
$Host.UI.RawUI. [tab]

$Host.UI.RawUI.get_BackgroundColor().Ge [tab] [tab]

PoSH>$Host.UI.RawUI.Fo [tab]

Now the following changes are made from the default tab handling :

# - Methods and properties of types

[regex]::M [tab]

# - tab completion on types.
[system.ma [tab]
[System.Management.Ma [tab] [tab]

# DBMwS: Added Progressbar and Scoped variable name expansion

$env:A [tab]

$global:dt [tab]

# - shows get_ methods

removed filter to also see get_ methods handy for WMI and AD

# - MultiLevel variable Tab Completion

PoSH>$Host.UI.RawUI.Fo [tab]

# - Bracet Removal

this one I did add for new-object use, as a shortcut so that I can use tabcompletion on the -TypeName parameter, I type a '[' complete the typename, type '=' and [tab] and the braces are removed.

new-object [s [tab]
new-object [System.Ma [tab]
new-object [System.Management.Ma [tab]
new-object [System.Management.ManagementClass]
new-object [System.Management.ManagementClass]= [tab]
new-object System.Management.ManagementClass

# show assemblyname in progressbar

just a visual change.

and here is the new function TabExpansion function :.

# TabExpansion.ps1
# Version 0.4
# Replacement of default TabExpansion function
# /\/\o\/\/ 2006

function TabExpansion {

# This is the default function that gets called for tab expansion.
# Edited by /\/\o\/\/ from the original to handle :
# - Cached tab completion on types (janel / mow).
# - Methods and properties of types
# - shows get_ methods
# - MultiLevel variable Tab Completion
# - Bracet Removal
# Edited by DBMwS: Added Progressbar and Scoped variable name expansion

param($line, $lastWord)

begin {
$_Method = [Management.Automation.PSMemberTypes] 'Method,CodeMethod,ScriptMethod,ParameterizedProperty'
$_ScopeNames = @("global", "local", "script", "private")

process {
switch -regex ($lastWord)
# Handle methods of Types (/\/\o\/\/)..
'(\[.*\])::(\w*)' {
invoke-expression "$($matches[1]) gm -static" where {$_.name -like "$($matches[2])*"} % {
if ($_.MemberType -band $_Method) {
"$($matches[1])::$($_.name)" + '('
} Else {

# Remove Brackets from typename (/\/\o\/\/)
'(\[.*\])=(\w*)' {

# Cache and Handle namespace and TypeNames (/\/\o\/\/) ..
'\[(.*)' {
$matched = $matches[1]
# only the first time Fill a DataTable with Typenames,namespaces and dotCount (level)
if (!($global:dtAssemblies)) {
$global:dtAssemblies = New-Object System.Data.Datatable
$assemblies = [appdomain]::CurrentDomain.getassemblies()
[void] ($assemblies % {$i = 0} {
[int]$assemblyProgress = ($i * 100) / $assemblies.Length
write-progress "Adding Assembly $($_.getName().name):" "$assemblyProgress" -perc $assemblyProgress
$types = $_.GetTypes()
$types % {$j = 0} {
if (($j % 200) -eq 0) {
[int]$typeProgress = ($j * 100) / $types.Length
write-progress "Adding types percent complete :"`
"$typeProgress" -perc $typeProgress -id 1

$dc = $_.fullName.split(".").count - 1
$ns = $_.namespace
write-progress "Adding types percent complete :" "100" -perc 100 -id 1

# actual tab completion
$dots = $matches[1].split(".").count - 1
switch ($dots) {
0 {"[System","[Microsoft"}
Default {
$res = @()
$res += $global:dtAssemblies.select("ns like '$($matched)%' and dc = $($dots + 1)")
select -uni ns % {"[$($_.ns)"};
$res += $global:dtAssemblies.select("name like '$($matched)%' and dc = $dots") % {"[$($_.name)]"}

# Handle property and method expansion (MultiLevel added /\/\o\/\/)...
'\$(\w+)\.(.*)' {
$variableName = $matches[1]
$val = '$' + $matches[1]
$level = $matches[2].split('.').count
if ($level -gt 1) {
$ofs = '.';$val = '$' + $variableName + ".$($matches[2].split('.')[0..($level -2)])"
$pat = $matches[2].split('.')[($level -1)] + '*'
# /\/\o\/\/ removed : -and $n -notmatch '^[ge]et_'
# to get get_ methods on WMI and AD objects
invoke-expression "Get-Member -inputobject $val" where {$n = $_.name; $n -like $pat } foreach {
if ($_.MemberType -band $_method)
# Return a method...
$val + '.' + $_.name + '('
else {
# Return a property...
$val + '.' + $_.name

# Handle expansions for both "Scope Variable Name" and "Type Variable Names" (DbmwS)
'(.*^\$)(\w+):(\w*)$' {
$type = $matches[2]; # function, variable, etc.. that are not scopes
$prefix = $matches[1] + $type; # $ + function
$typeName = $matches[3]; # e.g. in '$function:C', value will be 'C'

if ($_ScopeNames -contains $type) {
# Scope Variable Name Expansion
foreach ($scopeVariable in
(Get-Variable "$($typeName)*" -Scope $type Sort-Object name)) {
$prefix + ":" + $scopeVariable.Name
} else {
# Type name expansion($function:, $variable, $env: ,etc)
foreach ($t in (Get-ChildItem ($type + ":" + $typeName + '*') Sort-Object name)) {
$prefix + ":" + $t.Name

# Handle variable name expansion (original)...
'(.*^\$)(\w+)$' {
$prefix = $matches[1]
$varName = $matches[2]
foreach ($v in Get-Childitem ('variable:' + $varName + '*')) {
$prefix + $v.name

# Do completion on parameters (original) ...
'^-([\w0-9]*)' {
$pat = $matches[1] + '*'

# extract the command name from the string
# first split the string into statements and pipeline elements
# This doesnt handle strings however.
$cmdlet = [regex]::Split($line, '[;]')[-1]

# Extract the trailing unclosed block
if ($cmdlet -match '\{([^\{\}]*)$') {
$cmdlet = $matches[1]

# Extract the longest unclosed parenthetical expression...
if ($cmdlet -match '\(([^()]*)$') {
$cmdlet = $matches[1]

# take the first space separated token of the remaining string
# as the command to look up. Trim any leading or trailing spaces
# so you dont get leading empty elements.
$cmdlet = $cmdlet.Trim().Split()[0]

# now get the info object for it...
$cmdlet = @(Get-Command -type 'cmdlet,alias' $cmdlet)[0]

# loop resolving aliases...
while ($cmdlet.CommandType -eq 'alias') {
$cmdlet = @(Get-Command -type 'cmdlet,alias' $cmdlet.Definition)[0]

# expand the parameter sets and emit the matching elements
foreach ($n in $cmdlet.ParameterSets Select-Object -expand parameters) {
$n = $n.name
if ($n -like $pat) { '-' + $n }
} # EO switch
} # EO Process

you can past al code to a PowerShell console,
or save it to a file and start it dotsourced (from your profile):

. .\Tabcompletion.ps1


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?