[Powershell]

By StijnC at June 24, 2010 09:33
Filed Under: Powershell, Microsoft, Update

The Powershell team released Windows PowerShell 2.0 and WinRM 2.0 for pre-Windows 7 operating systems on Windows Update. This non-security, optional update is designed for Windows Server 2008 SP2, Windows Vista SP2, Windows Server 2003 SP2, and Windows XP SP3.

Windows PowerShell 2.0 and WinRM 2.0 are also available as part of  the Windows Management Framework (WMF) Core Package on the  Microsoft Download Center and Windows Server Update Services (WSUS).

The WMF Core Package available on the Microsoft Download Center and the Windows Update release contain the same binaries of the products, so you can now download them from either source. Because Windows PowerShell 2.0 is in-place upgrade to Windows PowerShell 1.0, we will no longer be offering Windows PowerShell 1.0 on Windows Update.

Windows PowerShell 2.0 appears as an option in a Windows Update scan only if the computer meets the following conditions.

  • The computer has at least Microsoft .NET Framework 2.0 SP1
  • The computer does not have a non-RTM (CTP, Beta, RCs etc.) release of Windows PowerShell. (Windows PowerShell 1.0 RTM can be installed.)

as found on the Powershell Team blog.

[Powershell] The scripting games 2010 are a wrap!

By StijnC at May 18, 2010 09:40
Filed Under: Powershell, Scripting Games 2010

2010_scriptgames_postgames The scripting games took place from 26th of April to May 7.
Although I sometimes struggled to get the scripts submitted on time,I really need to start working on my time management skills :), it was a lot of fun.
This is actually the first time I participated in this event and I was a awesome experience!
The community participating was all around twitter and the forums, any questions asked where rapidly answered,… etc.

I also liked the idea that multiple judges grated the scripts submitted. As there are several approaches you can tackle a problem, your vision might not always be the most efficient.
This actually brings me to the only drawback of the 2010 Scripting Games. If a second opinion would result in a downgrade of your script, it’s useful to have the ‘why’ communicated.

The greatest advantage of participating really comes down to one thing: I learned a lot.
The events were challenging and forced me to start exploring new items (like remoting, winforms/WPF,…), searching for useful information and so on.
Powershell is not about reading a book but getting your hands dirty and the 2010 Scripting Games provided that opportunity whether you’re a novice or advanced scripter.

Anyway, all things need improvement but already now this experience was top of the bill!
See you all again next year!

Thanks to:
The judges,
The sponsors,
The Scripting Guys
And all the other I forgot

 

 

[Powershell] Quick reference April 2010 update

By StijnC at April 23, 2010 11:18
Filed Under: Powershell, Documentation

Quick reference guide to commonly-used Windows PowerShell commands. For best results, open the file in Microsoft Word, print the contents to legal-sized paper (8 inches by 14 inches), and fold the resulting printout in half, making a four-page booklet.

Powershell Quick reference

[Powershell] Scripting Games 2010 announced!

By StijnC at April 13, 2010 09:27
Filed Under: Community, Powershell, Scripting Games 2010

2010_scriptgames_badge1 The scripting games 2010 will start April 26th!

So head over to http://2010sg.poshcode.org, log in with either your Windows Live ID or OpenID, complete your profile,
and wait for the Games to begin on April 26, 2010.

More information can be found on the Hey Scripting Guy blog.

 

 

 

 

 

 

[Powershell] network module

By DimitriC at February 13, 2010 15:58
Filed Under: Network, Powershell

I have grouped all previous network related function into a Powershell module.
The use of modules has several advantages, as auto completion and detailed help is available for the functions.

Get-Ping
Get-Nicinfo
Get-Subnet

you can easily import the module (if the .psm1 file is not located in your powershell profile folder, you need to specify the full path):

   1: import-module network

and retrieve some more information:

   1: get-module network

network.psm1 (7.03 kb)

[Powershell] Get-Subnet

By DimitriC at February 13, 2010 15:57
Filed Under: Network, Powershell

The Get-subnet function retrieves the IP and subnet mask from the active network interface.
Using the IP and Subnet mask it will calculate the Subnet for the given computer name.
This function makes use of the Get-Nicinfo function.

   1: function Get-Subnet{
   2:     [CmdletBinding()] 
   3:     PARAM 
   4:     ( 
   5:         [Parameter(Position=1,
   6:                     Mandatory=$false,
   7:                     ValueFromPipeline = $true,
   8:                     Helpmessage="The computer name")] 
   9:         [string]
  10:         $computername="."
  11:     )
  12:     BEGIN
  13:     {
  14:         #set the erroractionpreference to SilentlyContinue. 
  15:         #(We're not concerned about offline machines)
  16:         $erroractionpreference = "SilentlyContinue"
  17:         $result = @()
  18:     }
  19:     PROCESS
  20:     {
  21:         $object = new-object Object
  22:         $object| add-member Noteproperty Name -Value $computername
  23:         #makes use of the Get-Nicinfo function
  24:         $info = Get-Nicinfo -Computername $computername 
  25:         $ip =  $info.IPAddress[0]
  26:         $subnetmask = $info.Subnet[0]
  27:         $object| add-member Noteproperty IP -Value $ip
  28:         $object| add-member Noteproperty subnetMask -Value $subnetmask
  29:     
  30:         $ips = $ip.split(".")   
  31:         $subnetmasks = $subnetmask.split(".")   
  32:         $boundary = $null  
  33:         
  34:         for ($i=0; $i -lt 4; $i++ )   
  35:         {  
  36:             $boundary += [string]($ips[$i] -band $subnetmasks[$i])  
  37:             if($i -lt 3)  
  38:             {  
  39:                 $boundary += "."  
  40:             }  
  41:         } 
  42:         $object| add-member Noteproperty subnet -Value $boundary
  43:         $result +=$object
  44:     }
  45:     END
  46:     {
  47:         $result
  48:     }
  49: }

Get-Subnet.ps1 (1.15 kb)

[Powershell] Get-Nicinfo

By DimitriC at February 12, 2010 14:17
Filed Under: Network, Powershell

This function retrieves all available information for a network interface card. The NIC can have multiple adapters.

   1: function Get-NicInfo {
   2:     [Cmdletbinding()]
   3:     PARAM
   4:     (
   5:          [Parameter(Position=1,
   6:                     Mandatory=$false,
   7:                     ValueFromPipeline = $true,
   8:                     Helpmessage="The computer name")] 
   9:         [string]$computername = "localhost",
  10:         [Parameter(Position=2,
  11:                     Mandatory=$false,
  12:                     Helpmessage="Only active adapter information")]
  13:         [boolean]$active = $true            
  14:     )
  15:     BEGIN
  16:     {
  17:         $results = @()
  18:         #set the erroractionpreference to SilentlyContinue. 
  19:         #(We're not concerned about offline machines)
  20:         $erroractionpreference = "SilentlyContinue"
  21:     }
  22:     PROCESS
  23:     {
  24:         $AllAdapters = @("")
  25:         #Check if $Active = $true
  26:         if (-not $active) {
  27:             $Adapters = Get-Wmiobject Win32_NetworkAdapterConfiguration `
  28:             -Computername $computername 
  29:         } 
  30:         else {
  31:             $Adapters = Get-Wmiobject Win32_NetworkAdapterConfiguration `
  32:             -Computername $computername |`
  33:             Where-Object{$_.IPEnabled -eq $True}
  34:         }
  35:         
  36:         #Loop thru all adapters
  37:         ForEach($Adapter In $Adapters)
  38:         {
  39:             [String]$DNSServers = ""
  40:             $Adapters2 = Get-Wmiobject Win32_NetworkAdapter -Computername $pc `
  41:             | Where-Object{$_.Caption -eq $Adapter.Caption}
  42:             [String]$NetID = $Adapters2.NetConnectionID
  43:             If($Adapter.DNSServerSearchOrder -ne $Null)
  44:             {
  45:                 ForEach($Address In $Adapter.DNSServerSearchOrder)
  46:                 {
  47:                     $DNSServers += "[" + $Address + "]"
  48:                 }
  49:             }
  50:             
  51:             $result = new-object object
  52:             $result | add-member Noteproperty PC $pc.ToUpper()
  53:             $result | add-member Noteproperty NETID `
  54:             $NETID
  55:             $result | add-member Noteproperty Description `
  56:             $Adapter.Description
  57:             $result | add-member Noteproperty MACAddress `
  58:             $Adapter.MACAddress
  59:             $result | add-member Noteproperty IPAddress `
  60:             $Adapter.IPAddress
  61:             $result | add-member Noteproperty Subnet `
  62:             $Adapter.IPSubnet
  63:             $result | add-member Noteproperty DHCPEnabled `
  64:             $Adapter.DHCPEnabled
  65:             $result | add-member Noteproperty DHCPServer `
  66:             $Adapter.DHCPServer
  67:             $result | add-member Noteproperty DNSServers `
  68:             $DNSServers
  69:             $result | add-member Noteproperty WINSPrimaryServer `
  70:             $Adapter.WINSPrimaryServer
  71:             $result | add-member Noteproperty WINSSecondaryServer `
  72:             $Adapter.WINSSecondaryServer
  73:             $result | add-member Noteproperty DomainDNSRegistrationEnabled `
  74:             $Adapter.DomainDNSRegistrationEnabled
  75:             $result | add-member Noteproperty FullDNSRegistrationEnabled `
  76:             $Adapter.FullDNSRegistrationEnabled
  77:             $result | add-member Noteproperty WINSEnableLMHostsLookup `
  78:             $Adapter.WINSEnableLMHostsLookup
  79:             
  80:             $results += $result
  81:         }
  82:     }
  83:     END
  84:     {
  85:         return $results
  86:     }
  87: }
 
Get-NicInfo.ps1 (3.40 kb)

[Powershell] Windows PowerShell Quick Reference

By DimitriC at February 11, 2010 11:16
Filed Under: Powershell, Help

Quick reference guide to commonly-used Windows PowerShell commands.
For best results, open the file in Microsoft Word, print the contents to legal-sized paper (8 inches by 14 inches),
and fold the resulting printout in half, making a four-page booklet.

Download the Quick Reference

[Powershell] Get-ping

By DimitriC at February 11, 2010 10:01
Filed Under: Powershell, Network

This is a function that gets the ping result for a certain client.
The function does only check if the client replies or not. if it replies, the current IP gets displayed.
Otherwise a “Offline” text will be displayed. This means the Hostname is offline or faulty.

The function takes a hostname as parameter and makes use of the System.Net.NetworkInformation to get the “ping” information.

   1: function Get-ping {
   2:     [CmdletBinding()] 
   3:     PARAM 
   4:     ( 
   5:         [Parameter(Position=1,
   6:                     Mandatory=$false,
   7:                     ValueFromPipeline = $true,
   8:                     Helpmessage="The computer name")] 
   9:         [string]
  10:         $computername="."
  11:     )
  12:     BEGIN
  13:     {
  14:         $result = @()
  15:         #set the erroractionpreference to SilentlyContinue. 
  16:         #(We're not concerned about offline machines)
  17:         $erroractionpreference = "SilentlyContinue"
  18:     }
  19:     PROCESS
  20:     {
  21:         $object = new-object Object
  22:         $object| add-member Noteproperty PC $computername.ToUpper()    
  23:         $ping = new-object System.Net.NetworkInformation.Ping
  24:         $Reply = $ping.send("$computername")
  25:         if ($Reply.status –eq “Success”) 
  26:         {
  27:                 $object| add-member Noteproperty Status `
  28:                         -Value $reply.Address.IPAddressToString
  29:         }
  30:         else 
  31:         {    
  32:             $object| add-member Noteproperty Status Offline
  33:         }
  34:         #Add the result to the array
  35:         $result += $object
  36:         $object = $null
  37:         
  38:     }
  39:     END
  40:     {
  41:         $result
  42:     }
  43: }

 Get-ping.ps1 (1.65 kb)

Powershell – determine the site boundary for a given IP

By DimitriC at January 25, 2010 23:53
Filed Under: Configuration Manager, Powershell

DETAILS
Let's say you have an IP address on a client 10.109.238.142, with subnet mask of 255.255.255.192.  What subnet is that address on? 
Well, in order to calculate that, the "book" says you take that first octet of the address and convert it to binary, and convert the first octet of the mask and convert it to binary, and then "AND" the bits together...well I'm going to spare you the bitwise lesson and just show you how you can do that using SQL.
The ampersand (&) character is the BITWISE AND operator in SQL.  When you have a number BITWISE ANDed with another number, it will use the bits of the first number and the bits of the second number and perform the operation on the bits themselves.  So using the first octet of our IP address and subnet, we would do 10 & 255.

An easy way to determine the site boundary for a system, given its IP and Subnet mask:

   1: $ip = "192.168.17.24"
   2: $subnetmask = "255.255.255.128"
   3:  
   4: $ips = $ip.split(".")
   5: $subnetmasks = $subnetmask.split(".")
   6: $boundary = $null
   7:  
   8: for ($i=0; $i -lt 4; $i++ )
   9: {
  10:     $boundary += [string]($ips[$i] -band $subnetmasks[$i])
  11:     if($i -lt 3)
  12:     {
  13:         $boundary += "."
  14:     }
  15: }
  16: $boundary
  17:  
  18: $colItems = get-wmiobject -class "Win32_NetworkAdapterConfiguration"
  19: #get only the adapter that is enabled
  20: $colitems | where {$_.IPEnabled -eq 1} | select IPAddress, ipSubnet
  21: #if ipAddress contains more then 1 element, check for xxx.xxx.xxx.xxx 
  22: #same goes for the subnet
  23: #pipe into the function to get the boundary

Powershell Localized help

By DimitriC at January 25, 2010 11:18
Filed Under: Powershell

[Powershell] export info to Excel

By StijnC at July 30, 2009 02:12
Filed Under: Microsoft, Office, Powershell

There is no cmdlet available to export content directly to Excel. Sure you can use the ‘Export-csv’ cmdlet exporting the object(s) to a comma delimited file and use the generated file as a base.

But nevertheless you can address Excel via the com interface. Powershell facilitates the use of com objects via the ‘new-object’ cmdlet in conjunction with the –-ComObject parameter.

   1: $excel = New-Object -comobject Excel.Application

Once we have our Excel object, we can start adding a workbook and worksheets to the newly created workbook accordingly.

   1: #Add a workbook
   2: $workbooks = $excel.Workbooks.Add()
   3: #Select the Worksheet collection in the workbook (standard default = 3)
   4: $worksheets = $workbooks.Worksheets
   5: #Select the first worksheet
   6: $worksheet = $worksheets.Item(1)

Now that we have an active sheet, we can start adding data. lets get all the running processes and dump the information gathered into the sheet.

   1: #Now collect the data we want to export
   2: $processes = Get-Process
   3: $lastcell = $processes.Count
   4: for ($index = 0; $index -lt $lastcell; $index++) {
   5:     $worksheet.Cells.Item($index+1,1) = $processes[$index].Id
   6:     $worksheet.Cells.Item($index+1,2) = $processes[$index].ProcessName
   7: }

As we are not limited to inserting data, we can easily add some calculations to the sheet as well using the excel functions. 

   1: $cell = $worksheet.Cells.Item(3,3)
   2: $cell.Formula = "=TODAY()"

ExcelPowershell_Formula As we all now, graphs pretty things up and management is fond of them.
So let’s add a simple column chart to the current Workbook to visualize the data.

   1: #Lets select our data range
   2: $range = $worksheet.usedRange
   3: #Now add our charts to the workbook
   4: $workbooks.Charts.Add() | out-null
   5: #and select a chart type
   6: $workbooks.ActiveChart.chartType = [microsoft.office.interop.excel.xlChartType]::xlConeCol
   7: #Set the data source
   8: $workbooks.ActiveChart.SetSourceData($range)

ExcelPowershellChart For more information regarding the Charttypes, see MSDN Excel Charttype Enumeration.
Now lets use a template excel file and dumb the running process data into the predefined range.

   1: #Create the Excel com object
   2: $excel = New-Object -comobject Excel.Application
   3: #Open the workbook
   4: $workbooks = $excel.Workbooks.Open("C:\Users\StijnC\Documents\Test.xlsx")
   5: #get a hold of all the worksheets
   6: $worksheets = $workbooks.Worksheets
   7: #Select the first worksheet
   8: $worksheet = $worksheets.Item(1)
   9: #Now collect the data we want to export
  10: $processes = Get-Process
  11: $lastcell = $processes.Count
  12: for ($index = 0; $index -lt $lastcell; $index++) {
  13:     $worksheet.Cells.Item($index+1,1) = $processes[$index].Id
  14:     $worksheet.Cells.Item($index+1,2) = $processes[$index].ProcessName
  15: }

ExcelPowerShellTemplate

The last action that still remains is saving the excel file and disposing the objects.

   1: #close workbook and dispose the objects
   2: $workbooks.Save()
   3: $excel.Quit()
   4: $dummy = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($worksheet)
   5: $dummy = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($worksheets)
   6: $dummy = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($workbooks)
   7: $dummy = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel)

For some reason the Excel process keeps on running.So we kill all excel processes as well.
   1: #if any processes left, kill them
   2: if (ps excel) { kill -name excel}


So its really up to you to define all formatting in a template or create everything from scratch.
Now, this all is quite easy when using USA language settings, try using different settings and all this breaks.powershell regional settings
Even setting the language settings explicit does not solve the problem. You need to define the language settings every time.
The previously defined settings are only valid for the current thread. As Powershell uses a different thread for each command line, this solution is not really feasible.

You could go for a superb function “Using-Culture”, more info can be found on the Powershell Team Blog.
Or we could make sure that all our Excel programming runs in the same thread.
Welcome “script blocks”!

   1: & {
   2: #Create a Culture
   3: $enUS = [System.Globalization.CultureInfo]::CreateSpecificCulture("en-US")
   4: #Set the Current thread Culture to en-US
   5: [System.Threading.Thread]::CurrentThread.CurrentCulture = $enUS
   6: #Create the Excel com object
   7: $excel = New-Object -comobject Excel.Application
   8: #Open the workbook
   9: $workbooks = $excel.Workbooks.Add()
  10: $worksheets = $workbooks.Worksheets
  11: #Select the first worksheet
  12: $worksheet = $worksheets.Item(1)
  13: #Now collect the data we want to export
  14: $processes = Get-Process
  15: $lastcell = $processes.Count
  16: for ($index = 0; $index -lt $lastcell; $index++) {
  17:     $worksheet.Cells.Item($index+1,1) = $processes[$index].ProcessName
  18:     $worksheet.Cells.Item($index+1,2) = $processes[$index].WS
  19: }
  20: #Lets select our data range
  21: $range = $worksheet.usedRange
  22: #Now add our charts to the workbook
  23: $workbooks.Charts.Add() | out-null
  24: #and select a chart type
  25: $workbooks.ActiveChart.chartType = [microsoft.office.interop.excel.xlChartType]::xlConeCol
  26: #Set the data source
  27: $workbooks.ActiveChart.SetSourceData($range)
  28: $workbooks.SaveAs('C:\Users\StijnC\Documents\Process.xlsx')
  29: $excel.Quit()
  30: }

we define the full script as a “script block” and all the magic just works. once we defined the locale.

 

 

 

 

 

 

 

 

 

 

 

 

 

ExcelPowershellFinal

[Powershell] – renaming folders

By StijnC at January 23, 2009 00:19
Filed Under: Powershell

Last day I wanted to have uniform folder names, some of the folders currently have a set of ‘[‘, ‘]’ chars containing dates and some additional info afterwards.
As this was not really necessary and only makes the name longer then needed I decided to rename them, of course using Powershell.
Initially I needed to collect a list of all items:

gci $pwd -recurse

But i was only interested in the folders, so a where clause is in order:

gci $pwd -recurse | where {$_.Mode -match "d"}

Now that we have a list of all folders, we can start with renaming them leaving all chars as from the first ‘[‘:
after a lot of struggling and my one liner not working  I turned to good all friend ‘Google’ and the solution was found on  Mike Ormond's Blog.
Let’s give it another spin:

gci $pwd | where {$_.Mode -match "d"} | move-item -dest { join-path $pwd ([regex]'\[(.*)').replace($_.Name, "")}

nevertheless i got a new error:

Move-Item : The process cannot access the file because it is being used by another process.
At line:1 char:50 gci $pwd | where {$_.Mode -match "d"} | move-item  <<<< -dest { join-path $pwd ([regex]'\[(.*)').replace($_.Name, "")}

but as i looked into my directory, all folders where renamed. so i decided to add the following switch:

-ea SilentlyContinue –ev errorlog

Bare in mind that it is not always wise to let Powershell continue on errors, but as it did the job for me…
the variable $errorlog still holds all errors encountered in the IO operation and can easily be outputted to the console screen or a file.
the PowerShell Team has a great blog entry on 'Managing non-terminating errors' .