Categories

Monthly Archives: August 2009

PowerShell v2 help file

In PowerShell v2 we get a nice graphical help system that includes the cmdlets, the about files and and the User and Getting Started Guide. It doesn’t include the help for the optional modules though which is a pity.

The default locations on the Start Menu for PowerShell are Accessories – Windows PowerShell.  That is not very good placement considering Windows only really exists to give us somewhere to run Powershell :-)  

In these locations the help files are not visible. If you open up ISE then you can access the help file.

If you pin PowerShell to the start menu on Windows 7 then you get access to the help through the recent files menu.  The help file is located (on my system) at C:\Windows\Help\mui409\WindowsPowerShellHelp.chm

I keep a shortcut on my desktop and a shortcut to the version 1 graphical help file from the script center.  that way I can compare changes.

Technorati Tags: ,

Word Add a table

There seems to be two types of paragraph I create in Word documents – text or tables.  Lets start by adding a table.

001
002
003
004
005
006
007
008
009
function Add-Table {
    param (
        [int] $row = 2,
        [int] $col = 5
    )
    $global:paragraph = $doc.Content.Paragraphs.Add()
    $range = $paragraph.Range
    $global:table = $doc.Tables.Add($range,$row,$col)
}

 

The function Add-Table takes two integers as parameters. They define the rows and columns of the table.  The way that seems to work best is to add a paragraph to contain the table and then add the table into the paragraph.  If we just add the table to the document it overwrites the contents of the document with the table. oops.

Notice that I’m using global variables again so that they can be used across the environment.

Next time we will add some data to the table.

Technorati Tags: ,,,

Enable Ping

I’ve got a few talks coming up so need to build some more demo machines.  One thing I like to be able to do in the demo environment is ping between machines – sometimes necessary when testing things out but ping is disabled by the Windows firewall in Windows 2008 & R2.

James O’Neill has blogged about working with the Windows firewall at http://blogs.technet.com/jamesone/archive/2009/02/18/how-to-manage-the-windows-firewall-settings-with-powershell.aspx

To just set ping on

001
002
003
004
005
006
007
008
009
$fw = New-Object -ComObject HNetCfg.FWPolicy2
#$fw.Rules | Format-Table Name, Enabled, Direction -AutoSize

$fw.Rules | where {$_.Name -like "File and Printer Sharing (Echo Request - ICMPv4-In)"} | 
foreach {$_.Enabled = $true}

$fw.Rules | where {$_.Name -like "File and Printer Sharing (Echo Request - ICMPv4-In)"} | 
Format-Table Name, Direction, Protocol, Profiles, Enabled -AutoSize

Use the HNetCfg.FWPolicy2  COM object  and enable the rules for "File and Printer Sharing (Echo Request - ICMPv4-In)".  There are similar rules for IPv6 if needed.  Blocking pings is just the opposite.

Technorati Tags: ,,

Module path

PowerShell v2 has 2 default locations for modules – in the install directory and in your profile.  My demo laptop is set to dual boot Windows 7 & Windows 2008 R2.  It would make sense to only maintain one set of files for the modules I write. There is a PowerShell automatic variable that sets where PowerShell looks for modules.  To add my own folder to that path I just add

$env:PSModulePath = "C:\Scripts\Modules;" + $env:PSModulePath

to my profile.  The modules will be available now from either machine.  Need to change drive letter in the Win 2008 profile but otherwise just the same.

Technorati Tags: ,

Word New Document change

I started experimenting with the New-WordDocument function and realised I needed to change it to make the variables usable across the functions.

001
002
003
004
005
function New-WordDocument {
    $global:word = New-Object -ComObject Word.Application
    $word.Visible = $true
    $global:doc = $Word.Documents.Add() 
}

 

Simple change is to make the variables global in scope.  This means they are available across the functions of the module and form with scripts and from the prompt.

Depending on what you want to do you may not need this change but as I want to eventually use the module functions from scripts it works for me.

Word New Document

Lets add another function to our module for working with Word.  Its time to create a new word document

001
002
003
004
005
function New-WordDocument {
    $word = New-Object -ComObject Word.Application
    $word.Visible = $true
    $Word.Documents.Add() | Out-Null
}

 

Create the object for word as before.  Set the visible property to true (we can’t use it if we can’t see it)  We then add a document.  The Out-Null I found was necessary on my Windows 7 & Office 2010 combination because a lot of stuff was generated that I didn’t want to see.  Try it without on other combinations.  I don’t remember it being so bad with Word 2007

Word Autocorrect

If you have been following this blog for awhile you will know that I build and rebuild machines on a reasonably frequent basis.  One drawback to this that I have to keep re-creating the Autocorrect entries.  I do a lot of technical writing much of which involves full names of products and correct capitalisation.  I saw an entry on the TechNet scripting center that showed how to add an entry to the autocorrect list.  It was in VBScript but thats not an issue as we can easily convert it to something more useful  :-)

I ended up with a module consisting of four functions

  • Get-AutoCorrectEntry
  • Export-AutoCorrectEntry
  • Add-AutoCorrectEntry
  • Import-AutoCorrectEntry

 

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
#Requires -version 2.0
function Get-AutoCorrectEntry {
    param (
        [switch] $all
    )
    $word = New-Object -ComObject Word.Application
    if ($all) {$word.AutoCorrect.Entries}
    else {$word.AutoCorrect.Entries | Select Name, Value}
    $word.Quit()
}
function Export-AutoCorrectEntry {
    param (
        [parameter(Mandatory=$true)]
        [string] $path
    )
   
    Get-AutoCorrectEntry | where {$_.Value -ne "*"} | Export-Csv -Path $path -NoTypeInformation
}
function Add-AutoCorrectEntry {
    param (
        [parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [string] $name,
       
        [parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [string] $value
                      
    )
    begin {
        $word = New-Object -ComObject Word.Application
        $ace = $word.AutoCorrect.Entries
    }
    process {$ace.Add($name, $value)}
    end {$word.Quit()}
   
}
function Import-AutoCorrectEntry {
    param (
        [parameter(Mandatory=$true)]
        [string] $path
    )
    Import-Csv -Path $path | Add-AutoCorrectEntry

}

 

Get-AutoCorrectEntry creates an object for Word and dumps the contents of the AutoCorrect Entries collection.  Default is to just display the name and the value where name is the bad text and value is the replacement text.  The –all switch dumps everything but we won’t usually need that info

Export-AutoCorrectEntry calls Get-AutoCorrectEntry add dumps the results to a file using Export-Csv.  Using where {$_.Value -ne "*"} restricts the output to the entries I’ve created rather than including Word’s own entries

Add-AutoCorrectEntry creates a new entry.  It takes name and value parameters then creates an object for word, gets the AutoCorrect Entries then uses the Add method to create the new entry.  I’ve used the begin/process/end scriptblocks so it behaves nicely on the pipeline

Import-AutoCorrectEntry reads a csv file then calls Add-AutoCorrectEntry

Next time I re-install Office I can dump the entries and then import them after installation.  I can even move my entries between machines.  I created this using Windows 7 and Office 2010 TP but there is no reason for it not to work with other versions of Office.

 

File download problem

If you are using the Office 2010 TP and try to download a word document through Internet Explorer you end up in a continuous loop of being asked for credentials.  The download site won’t recognise your local credentials so you can’t get the documents.  You do however get to see the URL from where the document is coming.

So the answer to this conumdrum is to use the BITS file transfer cmdlets in Windows 7.

Start by importing the module

Import-Module BitsTransfer

You can then download the files

Start-BitsTransfer -Source http://download.microsoft.com/download/F/2/1/F2146213-4AC0-4C50-B69A-12428FF0B077/Windows_Server_2008_R2_Failover_Clustering_In_Brief.doc -Destination c:\source
Start-BitsTransfer -Source http://download.microsoft.com/download/F/2/1/F2146213-4AC0-4C50-B69A-12428FF0B077/WS08%20R2%20Failover%20Clustering%20White%20Paper.doc -Destination c:\source

Typing the URLs is a pain but at least we can now get the things downloaded.

TCP Ports

I came across this post http://www.expta.com/2009/08/name-that-port.html that gives the well known service for a TCP\UDP port.  Useful script but its written in VBScript.  Needs to be in PowerShell.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
param ([int]$port)
$data = @'
1 = TCP Port Service Multiplexer
2 = Management Utility
3 = Compression Process
4 = Unassigned

.... lots more in here

48003 = Nimbus Gateway
48556 = com-bardac-dw
'@

$ports = ConvertFrom-StringData -StringData $data

$ports["$port"]

 

Easy.  Create a script called get-port. It takes an integer as a port number. The ports and services are held in a here string and then ConvertFrom-StringData is used to create a hash table.

We then look up the port to get the service.   Next trick is to turn it round so that we can find the port number given the string.  I’ll add that next post and put the whole string on my skydrive as its too long to publish here

 

Technorati Tags: ,

Windows 2008 R2 RTM

It hasn’t had the same level of fanfares but Windows Server 2008 R2 RTM is available for download from TechNet\MSDN.  I’ll be converting my test domain over the next few days and reporting on all the PowerShell goodies we get