Categories

Monthly Archives: June 2011

PowerShell web cast by Don Jones

Combining Output from Multiple Sources

Webcast: Combining Output from Multiple Sources REGISTER NOW

July 6, 2011, 12pm CST

Presented by: Don Jones

Learn how easy-to-make custom objects not only let you combine output from multiple sources, but also allow you to create calculated properties and columns, customize output formatting, and easily send your output to CSV files, XML files, HTML, or pretty much anything you like.

Don Jones is the founder of ScriptingAnswers.com and the lead scripting guru at SAPIEN Technologies. He’s the author or more than twenty books on information technology, including Managing Windows with VBScript and WMI, Advanced VBScript for Windows Administrators, and Windows PowerShell: TFM. Don has written and spoken extensively about scripting and automation for years, including columns in REDMOND Magazine, MCPMag.com, Microsoft TechNet Magazine, and more, as well as a series of scripting-related Webinars for Microsoft TechNet. Don is a multiple recipient of Microsoft’s MVP Award, and one of the industry’s strongest advocates for Windows administrative automation.

Registration URL:

http://www.idera.com/Events/RegisterWC.aspx?EventID=192&s=EM_PSExpert _PSWC

Scripting Guy discusses PAM modules

My codeplex project publishing PowerShell Admin Modules (PAM) is discussed in this post

http://blogs.technet.com/b/heyscriptingguy/archive/2011/06/29/don-t-write-wmi-scripts-use-a-powershell-module.aspx

In particular the Get-OSInfo function from the PAMSysInfo module is heavily featured

UK PowerShell Group–June 2011 PowerShell and Office – slides and scripts

As promised on the Live Meeting the slides and scripts are now available at

https://skydrive.live.com/?wa=wsignin1.0&cid=43cfa46a74cf3e96#!/?cid=43cfa46a74cf3e96&sc=documents&uc=1&id=43CFA46A74CF3E96%212924!cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%212924

UK PowerShell Group–July meeting advance warning

The UK PowerShell group will be presenting a Live Meeting – Tuesday 26 July 2011 @ 7.30pm BST

Subject – PowerShell Remoting

More details to follow

IE history to CSV

Back in April last year I wrote a post about viewing IE history

http://msmvps.com/blogs/richardsiddaway/archive/2010/04/13/ie-history.aspx

I had a comment left asking how this could be put into a CSV file

We’ll start by turning the script into an advanced function that outputs an object

function get-iehistory {            
[CmdletBinding()]            
param ()            
            
$shell = New-Object -ComObject Shell.Application            
$hist = $shell.NameSpace(34)            
$folder = $hist.Self            
            
$hist.Items() |             
foreach {            
 if ($_.IsFolder) {            
   $siteFolder = $_.GetFolder            
   $siteFolder.Items() |             
   foreach {            
     $site = $_            
             
     if ($site.IsFolder) {            
        $pageFolder  = $site.GetFolder            
        $pageFolder.Items() |             
        foreach {            
           $visit = New-Object -TypeName PSObject -Property @{            
               Site = $($site.Name)            
               URL = $($pageFolder.GetDetailsOf($_,0))            
               Date = $( $pageFolder.GetDetailsOf($_,2))            
           }            
           $visit            
        }            
     }            
   }            
 }            
}            
}


The main changes are to stop writing strings to the output and to create an object to put the data into.



Run the function by dot sourcing the file you have the script in – its easier to do this in ISE Then try these commands



get-iehistory
get-iehistory | export-csv iehistory.csv -TypeInformation
Import-Csv iehistory.csv

Setting Security permissions on an AD group

We saw how to create an AD security group here

http://msmvps.com/blogs/richardsiddaway/archive/2011/06/28/creating-ad-security-groups.aspx

 

This is how we can give a user full control of that group

function set-groupsecurity {            
[CmdletBinding()]            
param (            
 [string]$name            
)            
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()            
$root = $dom.GetDirectoryEntry()            
            
$search = [System.DirectoryServices.DirectorySearcher]$root            
$search.Filter = "(&(objectclass=group)(Name=$name))"            
$search.SizeLimit = 3000            
$result = $search.FindOne()            
            
$object = $result.GetDirectoryEntry()            
            
$sec = $object.ObjectSecurity            
            
## set the rights and control type            
$act = [System.Security.AccessControl.AccessControlType]::Allow            
$adrights = [System.DirectoryServices.ActiveDirectoryRights]::GenericAll            
            
## who does this apply to            
$domname = ([ADSI]"").Name            
$who = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "$domname", "jtest"            
            
# apply rule            
$newrule = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $who, $adrights, $act            
$sec.AddAccessRule($newrule)            
$object.CommitChanges()            
}


We get a directory object for the group and then get the ObjectSecurity. Create a new rule to allow full control. Assign it to user jtest (could just as easily be a group) and apply the rule

UK PowerShell UG–30 June 2011

The rescheduled UG session (via Live Meeting) on using Office products with PowerShell is tomorrow. Details from

http://msmvps.com/blogs/richardsiddaway/archive/2011/06/21/rescheduled-ug-meeting.aspx

Network Connection Ids

Yesterday I was looking at changing a Network connection id (the name that shows in Network and Sharing Center when you look at the adapters). I kept getting an error – either COM or number of arguments depending if I was running locally or remotely.

I eventually realised that I must be using a connection id that already existed in the Registry.  I tracked them down to

HKLM:\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}

This works for Windows 7 and Windows 2008 R2. Please check for other Windows versions.

This produces a bunch of subkeys of the form

{F913D3B9-DBE4-455C-8926-10E24AB4E68A}

Each of these has a subkey Connection with a value of Name that we are interested in

function get-Registryconnectionid{             
[CmdletBinding()]             
param (             
   [string]$computer="."             
)             
BEGIN{}#begin             
PROCESS{            
            
Write-Verbose "Reading registry keys for IDs"            
$HKLM = 2147483650            
$key = "SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}"            
$reg = [wmiclass]'\\.\root\default:StdRegprov'            
$subkeys = $reg.EnumKey($HKLM, $key)            
            
            
foreach ($name in $subkeys.snames){            
  if ($name -eq "Descriptions"){Continue}            
  $conkey = "SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\$name\Connection"            
  Write-Debug $conkey            
              
  $cvalue = "Name"            
  $id = $reg.GetStringValue($HKLM, $conkey, $cvalue)  ## REG_SZ            
              
  $ivalue = "DefaultNameIndex"            
  $index = $reg.GetDwordValue($HKLM, $conkey, $ivalue)  ## REG_DWORD            
  $connection = New-Object -TypeName PSObject -Property @{            
       Index = $index.uValue            
       Connection = $id.sValue            
    }            
  $connection              
}            
            
            
}#process             
END{}#end            
            
<# 
.SYNOPSIS
Retrieves network connection ids 

.DESCRIPTION
Retrieves network connection ids held in the registry.
This includes current and previous ids.

.PARAMETER  Computer
Computer name

.EXAMPLE
get-Registryconnectionid

.EXAMPLE
get-Registryconnectionid -computer server02

#>            
            
}


This uses the standard WMI methods to read a local or remote registry



The corresponding current values are given by



Get-WmiObject -Class Win32_NetworkAdapter | select NetConnectionId, Index



The two index values are not related

Quick Tip: Discovering service start accounts

Do you know which accounts are used to start the services running on your machines? if you need this information try:

Get-WmiObject -Class Win32_Service | select Name, DisplayName, StartName

For a remote machine this becomes

Get-WmiObject -Class Win32_Service -ComputerName Win7 | select Name, DisplayName, StartName

And for testing which services are started by a specific account use:

Get-WmiObject -Class Win32_Service -ComputerName Win7 | where {$_.StartName -eq 'NT Authority\LocalService'} | select Name, DisplayName, StartName

I wanted to use a WMI filter instead of Where-Object but it didn’t want to work

Creating AD security groups

Continuing my AD excursion for a while. I saw a forum post about creating AD groups and came up with this function

function new-securitygroup {            
[CmdletBinding()]            
param (            
 [string]$name,            
 [string]$ou,            
             
 [parameter(ParameterSetName="U")]            
 [switch]$universal,            
             
 [parameter(ParameterSetName="G")]            
 [switch]$global,            
             
 [parameter(ParameterSetName="DL")]            
 [switch]$domainlocal            
)            
$rootdse = [ADSI]""            
$adpath = "$ou,$($rootdse.distinguishedName)"            
Write-Debug $adpath            
            
# set constants for group types            
$globalgroup = 0x00000002            
$domainlocalgroup = 0x00000004            
$security = 0x80000000            
$universalgroup = 0x00000008            
            
$targetou = [ADSI]"LDAP://$adpath"            
            
switch ($psCmdlet.ParameterSetName) {            
 "DL" {            
        $grouptype1 = $security -bor $universalgroup            
        $grouptype2 = $security -bor $domainlocalgroup}            
 "G"  {$grouptype = $security -bor $globalgroup }            
 "U"  {$grouptype = $security -bor $universalgroup }            
 default {Write-Host "Error!!! Should not be here" }            
}            
            
$newgroup = $targetou.Create("Group", "cn=$name")            
$newgroup.SetInfo()            
            
if ($domainlocal) {            
  $newgroup.GroupType = $grouptype1            
  $newgroup.SetInfo()            
              
  $newgroup.GroupType = $grouptype2            
  $newgroup.SetInfo()            
}            
else {            
  $newgroup.GroupType = $grouptype            
  $newgroup.SetInfo()            
}              
$newgroup.samAccountname = $name            
$newgroup.SetInfo()            
}


 



Parameter sets are used to keep the group types mutually exclusive



Note how we have to change the group type to universal before changing to domain local



Examples of use are as follows



new-securitygroup -name test-g -ou "ou=All Groups" -global



new-securitygroup -name test-u -ou "ou=All Groups" -universal



new-securitygroup -name test-dl -ou "ou=All Groups" –domainlocal



 



Trying to change the group type and/or the samaccountname as you create the group will generate an error