Thursday, December 27, 2012

Transcripts : Leverage them

This post is a result of the query asked on the Facebook page of Bangalore PowerShell User Group.
When someone asks a question regarding a Script, it becomes very difficult to follow through it especially if it  is related to some very different domain like SQL, SharePoint (especially for me).

I personally feel one could attempt to even try answering the question if he knows what happens behind the scenes like the Verbose Output associated with the cmdlets one is executing and the type of Objects that are being emitted etc.
Someone could ask the beginners to pipe the Objects into the Get-Member cmdlet to see the intricacies of the Object, or the Process one follows. Here we can leverage transcripts.

Already transcripts are used by PowerShell Gurus in the presentations or trainings , so that later you can see them and find out what went in which order.

In short Transcripts capture whatever appears in the PowerShell Console host.

Note! Windows PowerShell ISE doesn't support the transcripts here but you can follow Scripting Guy's post to make transcripts from ISE as well.

To keep things a bit easier I am going to use PowerShell Console for this post.


The Secret Sauce

The another great feature which I as a beginner found great is that PowerShell follows Universal Code Execution Model, which in simple terms means whatever works in the Script non-interactively can also be run interactively in the Shell and vice-versa.
This is actually great because I can try something interactively on the PowerShell Console, if it works as expected....Grab the code and put it in a Script. It will work too...awesome isn't it.


Example

I would take an elaborate example here . Please bear with me...

Suppose I was trying something related to services like I am trying to change the "start mode" of a running service (I know this is a typical example here)


Suppose I got the following Script form somewhere or someone :

$spooler = Get-Service -Name spooler
if ($spooler.Status -eq 'running'){
Write-Verbose "The Print Spooler Service is running..Trying to change the start mode"
$spooler.startMode = "automatic" # try to set the start  mode here
}
else {
Write-Verbose "The Print Spooler Service is not running"
}

Now when I run it it throws an error "Property 'startMode' cannot be found on this object; make sure it exists and is settable."
I did something obviously wrong here. So if I post the script in some forum they will ask me to post the Error first , if the experienced Power Users are already familiar with the Error the solution will come right in. If not then they will ask you to post the result of when you pipe the $spooler to Get-Member to know exactly what you did wrong.
One would go ahead and simply paste the output in the forum where the formatting goes awry some time. Better way is to do this.

Start the Transcript and Execute the Script Code statement by statement. Also to make things much clearer, after an Object is created pipe it into Get-Member to give clarity on the Object being spitted out.




Now execute the next statement



After you are done. Issue cmdlet "Stop-Transcript".

Now see the Transcript file has captured whatever you did in the Console and it also has the Error which was generated.


Take the file created and post it alongside your Question in the Forum. Someone could see it and observe that there is no property named "startmode" on the Object captured in $spooler.....Hmmmm..so this is where it went wrong ( Who knew ;) )

Now this is a very simple scenario where the transcripts can also be used . You can get creative in supplying the Useful information to others by putting $verbosepreference = 'continue' to include verbose messages in the transcript too( my little POSH trick ).

You can do more with them just pipe yourself to Get-Creative !!

Sunday, December 09, 2012

ServerCore + Create Test Users using Facebook

So Recently my VHD got corrupted and had to make the VHD Boot again work. Thankfully I had all the PowerShell one-liners I used to get my Lab up in less time.

First of all I will add 100 test users by following this awesome Hey Scripting Guys Blog Post.

To make things a bit clear I am on a workstation with RSAT for Active Directory installed and my DC is a servercore machine.

Just to give a hint when I need to run a cmdlet to get any information from the AD, I need to specify the name of the DC with -Server  parameter from where I want to get the information but a new connection will be opened and closed for each cmdlet invocation.

For Example :
Get-ADForest -Server dexservercore.dexter.com

Better way explained in Active Directory PowerShell Blog is to map a PSDrive for better performance. Since I have only one DC in my test environment , when I Import the ActiveDirectory Module it will automatically map a PSDrive on my remote workstation.





Now I don't want to add users like TestUser01, TestUser02... So I began to think from where can I get the data to create few test users for my Domain....and the answer to it is what better than FaceBook :P

Below are the steps I carried out:

Create a new Organizational Unit
I used the following cmdlet to create an OU named 'IT' under dexter.com
   New-ADOrganizationalUnit -Name IT -Path 'dc=dexter,dc=com' -ProtectedFromAccidentalDeletion:$false

Get the relevant data from Facebook

To get the some basic info for the User I used already available PowerShell Module for Facebook( credits to the Developer). On a how to use this module see my earlier post.


Set up a New FB Connection and be ready to retrieve data from Facebook 
 

 You can see that I have stored all my FB friends in $friends, but it doesn't return much information. What can be done here..there is an another cmdlet Get-FBObjectData which returns objects with greater deal of information. So just expand the property ID and pipe it and use as below



Better save this valuable data as a facebook.xml which I will use later.....

Create the AD Users 

Now I have all the information I could gather from Facebook into an XML file for later use. Now I will do some manipulation with the Objects I get from ...Below is the Script block which I used.


Above is the Script block that I used later from the PowerShell ISE.
First import the XML data into variable $facebookdata then do some Object manipulation in order to be consistent with the AD User attributes. Finally pipe it into the New-ADUser cmdlet with the -path parameter specifying the OU in which the Users need to be created.

Note that there is a -whatif parameter added at last to just check if we are headed in the right direction. Execute the Script block to get something like below ouput



If you read it properly it tells our success story :)
Go ahead and remove the -whatif parameter and execute the Script block again

When I run the script block I get two errors :
Below one is because some of my friends have same name and the other one is because of some formatting issues in the name of some friends.





Finally verify the User creation:



That's all for today.
Thank you!