June 2010 - Posts

PowerShell UG – June meeting slides and recording

Thanks to everyone how joined the Live Meeting this evening – especially for the questions :-)

The slides and demo script are available for download from:

http://cid-43cfa46a74cf3e96.office.live.com/browse.aspx/PowerShell%20User%20Group/2010%20June

 

The recording of the session is available from:

Richard Siddaway has invited you to view a Microsoft Office Live Meeting recording.
View Recording
Recording Details
    Subject: PowerShell and DNS
    Recording URL: https://www.livemeeting.com/cc/usergroups/view
    Recording ID: NPP98R
    Attendee Key: Dj\J_)4}g

PowerShell User Group reminder

 

Don’t forget the PowerShell User Group Live Meeting – Tuesday 29 June @ 7.30 BST

Details from

http://msmvps.com/blogs/richardsiddaway/archive/2010/06/17/powershell-ug-meeting-dns.aspx

Posted by RichardSiddaway | with no comments

PowerShell and Visio – Documenting AD: 3

Up to now we have been dealing with a single level of OUs. There are few AD implementations that don’t have child OUs so how do we deal with them.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
function Add-Domain {
 param (
    [string]$name
 )
    $dom = $page.Drop($domain, 1, 11)
    $dom.Resize(1, 5, 70)
    $dom.Text = $name
    return $dom
 
}

function Add-Ou {
 param (
    [string]$name,
    [double]$x,
    [double]$y,
    $parent
)
    $ou = $page.Drop($orgunit, $x, $y)
    $ou.Resize(1, 5, 70)
    $ou.Text = $name   

    $link = $page.Drop($dircon,1,$y)
    $start = $link.CellsU("BeginX").GlueTo($parent.CellsU("PinX"))
    $end = $link.CellsU("EndX").GlueTo($ou.CellsU("PinX"))
   
    return $ou
}

$visio = New-Object -ComObject Visio.Application
$docs = $visio.Documents

## use blank drawing
$doc = $docs.Add("")

## set active page
$pages = $visio.ActiveDocument.Pages
$page = $pages.Item(1)

## Add a stencil
$mysten = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033\ADO_M.vss"
$stencil = $visio.Documents.Add($mysten)

## Add objects
$domain = $stencil.Masters.Item("Domain")
$orgunit = $stencil.Masters.Item("Organizational Unit")
$dircon = $stencil.Masters.Item("Directory connector")

$file = "manticore.txt"
$domname = ($file -split "\.")[0]

$ous = Get-Content $file

$dom = Add-Domain $domname

$y = 11
$x = 1

foreach ($ou in $ous) {
    $names = $ou -split ","
    $ouname = $names[0] -replace "ou=", ""
    $parent = $names[1].Remove(0,3)
    #$parent
   
    $y = $y - 0.75
   
    if ($parent -eq $domname) {  
        New-Variable -Name "$ouname" -Value (Add-ou $ouname ($x + 0.5) $y $dom) -Force
    }
    else {
        $linkto =  Get-Variable -Name $parent -ValueOnly
        New-Variable -Name "$ouname" -Value (Add-ou $ouname ($x + $names.length -2.5 ) $y $linkto) -Force
    }   
}

 

The difference here is in the way we handle the OUs.  We get the parent of the OU we are working with.  If the parent is the domain we link back to that as before. If its another OU we link to that.

A variable is created for every OU object in the diagram at the time we create it. We can then use get-variable to find the value of the variable to be our parent for linking

Listing all of the OUs in a domain

In this post - http://msmvps.com/blogs/richardsiddaway/archive/2010/06/13/powershell-and-visio-documenting-ad-2.aspx – I showed how to start creating a diagram of the OU structure in your AD domain.  In case you are wondering how to get a text file like the one I used check out PowerShell in Practice - http://www.manning.com/siddaway/ – especially Technique 103 on page 300

Extended properties

In the last post I showed how to read the Extended Properties of a Visio stencil. But how do we know how which property to use?

We can adapt our script to list the possible Extended Properties

001
002
003
004
005
$direc = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033"
$shell = New-Object -ComObject "Shell.Application"
$folder = $shell.Namespace($direc)

0..300 | foreach { "$_ $($folder.GetDetailsOf($null,$_))"}

 

On Windows 7 I counted 286 properties.  Its a long scroll but you will find what you want.

Identifying Visio Stencils

In the previous posts on using Visio I’ve shown how to load and use a particular stencil.  But how do you know which stencil to use?

One way is to use Windows Explorer, hover the mouse over the stencil and read the Extended File Properties. That’s a bit manual so we’ll look at producing a list of stencils and for what they are used. To do this we can’t use PowerShell directly but this is where things get real easy – we can use the scripting shell just like we did with VBScript.

001
002
003
004
005
006
007
008
$direc = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033"
$shell = New-Object -ComObject "Shell.Application"
$folder = $shell.Namespace($direc)

Get-ChildItem -Path $direc -Filter "*.vss" | foreach {
    $file = $folder.Items().Item($_.Name)
    "{0,-12} {1}" -f $_.Name, $($folder.GetDetailsOf($file,21))
}

 

Define the directory holding the Visio stencils – mine is Office 2010 on Windows 7.

Create an object for the shell and get the folder object using the Namespace method.

Jump back to PowerShell to run get-childitem on the folder using a filter of *.vss to restrict the output to stencils – always cheaper to filter at source.

We then use the Items() method of our folder to identify the file and use getdetailsof method to return the Title (Extended property number 21) of the stencil. The output is formatted using a .NET formatted string.

High Availability and Disaster Recovery: Chapter2

The first and second chapters of my book on Untangling High Availability and Disaster Recovery is available from

http://nexus.realtimepublishers.com/sgudb.php

 

Enjoy

Posted by RichardSiddaway | with no comments
Filed under: ,

PowerShell UG Meeting: DNS


When: Tuesday, Jun 29, 2010 7:30 PM (BST)


Where: Live Meeting webcast

*~*~*~*~*~*~*~*~*~*

Meeting will cover DNS, DNS best practice analyser, DNS WMI provider and DNSShell cmdlets from codeplex

Notes


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: NPP98R
    Entry Code: Dj\J_)4}g
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.

PowerShell and Visio – Documenting AD: 2

I’ve taken the script to add OUs to a drawing and modified it so that the addition is performed by a function.

I started with a text file containing some OUs

ou=England,dc=Maticore,dc=org
ou=Scotland,dc=Maticore,dc=org
ou=Wales,dc=Maticore,dc=org
ou=Ireland,dc=Maticore,dc=org
ou=Portugal,dc=Maticore,dc=org
ou=Belgium,dc=Maticore,dc=org
ou=Latvia,dc=Maticore,dc=org

Notice that they are all top level OUs – lets not get too ambitious!

 

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
function Add-Domain {
 param (
    [string]$name
 )
    $dom = $page.Drop($domain, 1, 11)
    $dom.Resize(1, 5, 70)
    $dom.Text = $name
    return $dom
 
}

function Add-Ou {
 param (
    [string]$name,
    [double]$x,
    [double]$y
)
    $ou = $page.Drop($orgunit, $x, $y)
    $ou.Resize(1, 5, 70)
    $ou.Text = $name   

    $dom_ou = $page.Drop($dircon,1,$y)
    $start = $dom_ou.CellsU("BeginX").GlueTo($dom.CellsU("PinX"))
    $end = $dom_ou.CellsU("EndX").GlueTo($ou.CellsU("PinX"))
       
}

$visio = New-Object -ComObject Visio.Application
$docs = $visio.Documents

## use blank drawing
$doc = $docs.Add("")

## set active page
$pages = $visio.ActiveDocument.Pages
$page = $pages.Item(1)

## Add a stencil
$mysten = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033\ADO_M.vss"
$stencil = $visio.Documents.Add($mysten)

## Add objects
$domain = $stencil.Masters.Item("Domain")
$orgunit = $stencil.Masters.Item("Organizational Unit")
$dircon = $stencil.Masters.Item("Directory connector")

$file = "manticore.txt"
$domname = ($file -split "\.")[0]

$ous = Get-Content $file

$dom = Add-Domain $domname

$y = 11

foreach ($ou in $ous) {
    $ouname = ($ou -split ",")[0] -replace "ou=", ""
   
    $y = $y - 0.75
      
    Add-ou $ouname 1.5 $y
}

The functions add the domain and OU objects to the drawing.  Only change is that I set the text property of the OU and domain.

The main body of the script creates the drawing as before.  Uses the file name to get the domain and then reads the file. It splits out the OU names and calculates the Y co-ordinate then adds the OU

Next up I need to deal with child OUs

PowerShell and Visio – Documenting AD: 1

If we take the concept of our last script that added objects to a drawing we can use this as the basis of a way to automate the documentation of our AD.

One of the first things we need to document is the OU structure.  If you have ever produced one of these it is a tedious affair and they are difficult to maintain. So lets automate it.

This is how we create a basic OU structure.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
$visio = New-Object -ComObject Visio.Application
$docs = $visio.Documents

## use blank drawing
$doc = $docs.Add("")

## set active page
$pages = $visio.ActiveDocument.Pages
$page = $pages.Item(1)

## Add a stencil
$mysten = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033\ADO_M.vss"
$stencil = $visio.Documents.Add($mysten)

## Add objects
$domain = $stencil.Masters.Item("Domain")
$ou = $stencil.Masters.Item("Organizational Unit")
$dircon = $stencil.Masters.Item("Directory connector")

$dom = $page.Drop($domain, 1, 11)
$dom.Resize(1, 5, 70)

$ou1 = $page.Drop($ou, 1.5, 10.25)
$ou1.Resize(1, 5, 70)

$ou2 = $page.Drop($ou, 1.5, 9.5)
$ou2.Resize(1, 5, 70)

$dom_ou1 = $page.Drop($dircon,2,10.25)
$start = $dom_ou1.CellsU("BeginX").GlueTo($dom.CellsU("PinX"))
$end = $dom_ou1.CellsU("EndX").GlueTo($ou1.CellsU("PinX"))

$dom_ou1 = $page.Drop($dircon,2,9.5)
$start = $dom_ou1.CellsU("BeginX").GlueTo($dom.CellsU("PinX"))
$end = $dom_ou1.CellsU("EndX").GlueTo($ou2.CellsU("PinX"))

 

The basic changes from last time are that I’m starting with a blank drawing and adding the Active Directory stencil.  Objects are added and resized as before.  I’m also using the directory connector object rather than the default connector.

If you look at the positions of the objects you can see that I’m automatically aligning them in vertical columns by defining the X co-ordinate.

This script is OK as an experiment to discover how things work but we usually have a lot more objects than this and the depth of the child OUs needs to be considered. We need to be able to read in the OU data and move some of this activity into functions so we can reuse the code.

That’s the next job.

Manning Deal of the Day

PowerShell in Practice pbook is today’s deal of the day at www.manning.com  - enter dotd0611cc in Pormotional Code box on check out

Posted by RichardSiddaway | with no comments
Filed under: ,

Powershell and Visio: Move objects and add text

Lets take our look a Visio a bit further and move objects around and change the text labels

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
## create visio document
$visio = New-Object -ComObject Visio.Application
$docs = $visio.Documents

## use basic template
$doc = $docs.Add("Basic Diagram.vst")

## set active page
$pages = $visio.ActiveDocument.Pages
$page = $pages.Item(1)

## Add a stencil
$mysten = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033\EntApp_M.vss"
$stencil = $visio.Documents.Add($mysten)

## Add objects
$server = $stencil.Masters.Item("Server")
$workstn = $stencil.Masters.Item("Workstation")

$shape1 = $page.Drop($server, 2, 2)
$shape2 = $page.Drop($workstn, 5, 5)

## Resize Objects
$shape1.Resize(1, 5, 70)
$shape2.Resize(1, 5, 70)

## Connect Objects
$connect = $page.Drop($page.Application.ConnectorToolDataObject,0,0)
$start = $connect.CellsU("BeginX").GlueTo($shape1.CellsU("PinX"))
$end = $connect.CellsU("EndX").GlueTo($shape2.CellsU("PinX"))

## move objects
$shape2.SetCenter(4,9)
$shape1.SetCenter(4,4)

## Add text
$shape1.Text = "File Server"
$shape2.Text = "My Workstation"

$doc.SaveAs("c:\scripts\visio\draw1.vsd")
$visio.Quit()

 

To move an object we can use the SetCenter method.  The numbers are X & Y co-ordinates.  The origin is at the bottom left corner (0,0).  Depending on what units and paper size you are using – using A4 I get 8,11 as an approximation to the top right corner so I’m guessing the co-ordinates represent inches. Check on your implementation.

The text is simply changed by setting the Text property as shown.

Now we have the basics of working with Visio – its time to think what we can do with it.

Powershell and Visio: connectors

Last time we looked at creating a Visio drawing and adding a couple of objects.  This time we will build on that and resize the objects and add a connector.

The Resize method on a shape is ONLY AVAIALBLE ON VISIO 2010

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
## create visio document
$visio = New-Object -ComObject Visio.Application
$docs = $visio.Documents

## use basic template
$doc = $docs.Add("Basic Diagram.vst")

## set active page
$pages = $visio.ActiveDocument.Pages
$page = $pages.Item(1)

## Add a stencil
$mysten = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033\EntApp_M.vss"
$stencil = $visio.Documents.Add($mysten)

## Add objects
$server = $stencil.Masters.Item("Server")
$workstn = $stencil.Masters.Item("Workstation")

$shape1 = $page.Drop($server, 2, 2)
$shape2 = $page.Drop($workstn, 5, 5)

## Resize Objects
$shape1.Resize(1, 5, 70)
$shape2.Resize(1, 5, 70)

## Connect Objects
$connect = $page.Drop($page.Application.ConnectorToolDataObject,0,0)
$start = $connect.CellsU("BeginX").GlueTo($shape1.CellsU("PinX"))
$end = $connect.CellsU("EndX").GlueTo($shape2.CellsU("PinX"))

$doc.SaveAs("c:\scripts\visio\draw1.vsd")
$visio.Quit()

 

As seems to be the case with the other Office applications once you have worked out how to create the document the rest is relatively straightforward.

This is the same code as last time except I use the Resize method to change the size – the parameters denote the top right hand corner (values 0-7 with 0 being middle top and proceeding clockwise), the amount to drag the corner (5) and the units – in this case millimeters

The connection is made using the connectortooldataobject and defining the start and end objects.

 

Thanks to Alan Renouf for his powershell script to document  VMware environments into Visio which forms the basis of these scripts so far.

PowerShell and Visio

I’ve blogged about using PowerShell with various members of the Office family before. I thought its about time I looked at Visio.  I use Visio quite a bit and it would be useful to be able to drive it with PowerShell

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
## create visio document
$visio = New-Object -ComObject Visio.Application
$docs = $visio.Documents

## use basic template
$doc = $docs.Add("Basic Diagram.vst")

## set active page
$pages = $visio.ActiveDocument.Pages
$page = $pages.Item(1)

## Add a stencil
$mysten = "C:\Program Files\Microsoft Office\Office14\Visio Content\1033\EntApp_M.vss"
$stencil = $visio.Documents.Add($mysten)

$server = $stencil.Masters.Item("Server")
$workstn = $stencil.Masters.Item("Workstation")

$shape1 = $page.Drop($server, 2, 2)
$shape2 = $page.Drop($server, 5, 5)

$doc.SaveAs("c:\scripts\visio\draw1.vsd")
$visio.Quit()

Office still uses COM objects so we need to create a Viso object and then the document and page we are working on.  We are using the basic template and are going to add a stencil for the Enterprise Applications. A couple of objects are created for the server and workstation shapes and then we drop them on to the page.

We can then save the drawing and quit visio.

A simple drawing that we will need to embellish but it shows how straight forward it is to automate the production of drawings. The great thing is that we can then go back into the drawing and manipulate it as we need.

Upgrade?

Live.com has been upgraded – biggest change seems to be to the SkyDrive and we now get the ability to use Web versions of Office. May or may not be useful.

Big downside is that the statistics on the blog have been removed. Can’t see who is accessing or number of hits.  BAD MOVE – not happy about that.

 Live Writer has stopped working as well - VERY VERY BAD MOVE - very unhappy about that

Posted by Richard Siddaway's Blog
Filed under:

Ranged letters

While I was playing around with the range operator I thought of this

001
002
003
004
005
$start = [byte][char]"a"
$finish = [byte][char]"h"

$start..$finish | 
foreach {New-Item -Path c:\test -Name "file$([char]$_).txt" -ItemType File}

 

Define your start and finish letters. Convert each to a char and then a byte.  This gives us the numeric value of the letter (ascii code).

We can then use those values in the range operator and create the files as we have already seen.

Posted by RichardSiddaway | with no comments
Filed under:

Using Range operator to generate letters

The range operator is used to generate a sequential set of numbers

1..10 | foreach {$_}

if we try this with letters

PS> a..j | foreach {$_}
The term 'a..j' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:5
+ a..j <<<<  | foreach {$_}
    + CategoryInfo          : ObjectNotFound: (a..j:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

However we can use the range operator to generate letters like this

## upper case
65..90 | foreach {"$_ $([char]$_)" }

## lower case
97..122 | foreach {"$_ $([char]$_)" }

using the ACSII codes.  if we want to create filea.txt – filej.txt  we can simply do this

97..106 | foreach {New-Item -Path c:\test -Name "file$([char]$_).txt" -ItemType File}

Nice and simple one line of PowerShell.

Posted by RichardSiddaway | with no comments
Filed under:

Using the range operator

One of the events in this years scripting games involved creating a set of files.  Many of the entries did something like this

001
002
003
$files = @("file1.txt", "file2.txt", "file3.txt", "file4.txt", "file5.txt", 
"file6.txt", "file7.txt", "file8.txt", "file9.txt", "file10.txt")
foreach ($file in $files) {New-Item -Path c:\test -Name $file -ItemType File}

 

A list of files is created and a foreach is used to call New-Item.  A variant on this used a for loop

for ($i=0; $i –le 9; $i++){New-Item -Path c:\test -Name $files[$i] -ItemType File}

 

There is a much easier way

001
1..10 | foreach {New-Item -Path c:\test -Name "file$_.txt" -ItemType File}

 

Whenever you have to deal with lists of things that are numerically sequential – try to use the range operator. 

Posted by RichardSiddaway | with no comments
Filed under:

Code in Posts

I’ve been asked a couple of times recently how I put the colour highlighted code into the posts on my blog(s).

I create the posts using Live Writer. The scripts are usually developed in PowerShell ISE.  I have a script I modified from

http://www.leeholmes.com/blog/MorePowerShellSyntaxHighlighting.aspx that creates an add-on to copy the script from ISE to the clipboard.

I then chose Edit-Paste Special from the Live Writer menu and select Keep Formatting.

Only issue is ensuring that the lines of code aren’t too long for  the display width on the blog.

Posted by RichardSiddaway | with no comments
Filed under: ,

PowerShell in Practice - published

The book is finally complete and available in its final form.  The ebook is available now from http://www.manning.com/siddaway/ and the print version will be available 7 June 2010.

Enjoy

Posted by RichardSiddaway | with no comments
Filed under: ,
More Posts Next page »