<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>snowland.se &#187; PowerShell</title>
	<atom:link href="http://www.snowland.se/category/powershell/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.snowland.se</link>
	<description>Rikard Rönnkvist blogging about Microsoft System Center and other management stuff...</description>
	<lastBuildDate>Mon, 23 Aug 2010 11:19:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Maintenance Mode via Powershell Remoting</title>
		<link>http://www.snowland.se/2010/08/23/maintenance-mode-via-powerhsell-remoting/</link>
		<comments>http://www.snowland.se/2010/08/23/maintenance-mode-via-powerhsell-remoting/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 11:19:46 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[OpsMgr]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Maintenance Mode]]></category>
		<category><![CDATA[Remoting]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=502</guid>
		<description><![CDATA[There are loads of scripts and GUIs that you can use to set Maintenance Mode in OpsMgr, but if you want to do this from a server that doesn&#8217;t have the OpsMgr-snapins for Powershell it&#8217;s a bit harder&#8230;
But then there is Powershell v2 and Remoting&#8230; It gives you the option to run a  scriptblock [...]]]></description>
			<content:encoded><![CDATA[<p>There are loads of scripts and GUIs that you can use to set Maintenance Mode in OpsMgr, but if you want to do this from a server that doesn&#8217;t have the OpsMgr-snapins for Powershell it&#8217;s a bit harder&#8230;</p>
<p>But then there is Powershell v2 and Remoting&#8230; It gives you the option to run a  scriptblock on another computer&#8230;</p>
<p>Just enable remoting on your RMS and then try this script from another machine:</p>
<pre class="brush: powershell;">
Function setMaintMode {
	PARAM (
		[string] $rmsHostname,
		[string] $agentName,
		[string] $Comment,
		[string] $Reason,
		[int] $Time
	)

	Invoke-Command -ComputerName $rmsHostname -scriptblock {
		PARAM (
			[string] $agentName,
			[string] $Comment,
			[string] $Reason,
			[int] $Time
		)

		Add-PSSnapin &quot;Microsoft.EnterpriseManagement.OperationsManager.Client&quot;
		Set-Location &quot;OperationsManagerMonitoring::&quot;
		New-ManagementGroupConnection -ConnectionString:localhost | Out-Null

		$computerClass = Get-MonitoringClass -name:Microsoft.Windows.Computer
		$computerCriteria = &quot;PrincipalName='&quot; + $agentName + &quot;'&quot;
		$computer = get-monitoringobject -monitoringclass:$computerClass -criteria:$computerCriteria

		if ($computer.InMaintenanceMode -eq $false) {
			$startTime = [System.DateTime]::Now
			$endTime = $startTime.AddMinutes($Time)

			New-MaintenanceWindow -startTime $startTime -endTime $endTime -Comment $comment -Reason $Reason -monitoringObject $computer
			return $true
		}  else {
			# Allready in maintenance mode
			return $false
		}

	} -ArgumentList $agentName, $Comment, $Reason, $Time
}

setMaintMode -rmsHostname &quot;rmsserver.domain.local&quot; -agentName &quot;currentserver.domain.local&quot; -Comment &quot;Some comment&quot; -Time 30 -Reason &quot;PlannedOperatingSystemReconfiguration&quot;
</pre>
<p>What it does is that it run&#8217;s the OpsMgr-specific parts on the RMS instead on your local machine&#8230; so with that in place it&#8217;s easy to create a GUI around it and then spread a shortcut to all your servers that have Powershell v2 installed.</p>
<p><strong>Notes:</strong><br />
The quick and dirty way to enable remoting on your rms, start cmd as an administrator and run <strong>winrm quickconfig</strong><br />
<a href="http://blogs.msdn.com/b/powershell/archive/2008/05/10/remoting-with-powershell-quickstart.aspx">Here</a> can you find a quick intro to PS Remoting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/08/23/maintenance-mode-via-powerhsell-remoting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Change a folder LastWriteTime based on files within it</title>
		<link>http://www.snowland.se/2010/06/21/change-a-folder-lastwritetime-based-on-files-within-it/</link>
		<comments>http://www.snowland.se/2010/06/21/change-a-folder-lastwritetime-based-on-files-within-it/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 13:42:37 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Date]]></category>
		<category><![CDATA[Folders]]></category>
		<category><![CDATA[Function]]></category>
		<category><![CDATA[LastWriteTime]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=492</guid>
		<description><![CDATA[A few days ago I wrote a script that copies some files. Did notice that everything except the date on the folders were ok. So I added a few more lines of powershell code.
Did find a few suggestions on the web, but I like this one&#8230;. Since I wrote it.  

Function Set-FolderDate {
	Param (
		[string] [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I wrote a script that copies some files. Did notice that everything except the date on the folders were ok. So I added a few more lines of powershell code.</p>
<p>Did find a few suggestions on the web, but I like this one&#8230;. Since I wrote it. <img src='http://www.snowland.se/wp/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<pre class="brush: powershell;">
Function Set-FolderDate {
	Param (
		[string] $Path
	)
	Trap  [Exception] {
		Write-Debug $(&quot;TRAPPED: &quot; + $_.Exception.Message);
		Write-Verbose &quot;Could not change date on folder (Folder open in explorer?)&quot;
		Continue
	}

	# Get latest filedate in folder
	$LatestFile = Get-ChildItem $Path | Sort-Object LastWriteTime -Descending | Select-Object -First 1

	# Change the date, if needed
	$Folder = Get-Item $path
	if ($LatestFile.LastWriteTime -ne $Folder.LastWriteTime) {
		Write-Verbose &quot;Changing date on folder '$($Path)' to '$($LatestFile.LastWriteTime)' taken from '$($LatestFile)'&quot;
		$Folder.LastWriteTime = $LatestFile.LastWriteTime
	}

	Return $Folder
}

Set-FolderDate -Path &quot;D:\temp&quot;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/06/21/change-a-folder-lastwritetime-based-on-files-within-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unzip multiple files via Powershell</title>
		<link>http://www.snowland.se/2010/06/01/unzip-multiple-files-via-powershell/</link>
		<comments>http://www.snowland.se/2010/06/01/unzip-multiple-files-via-powershell/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 11:41:06 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[Progressbar]]></category>
		<category><![CDATA[Unzip]]></category>
		<category><![CDATA[Zip]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=488</guid>
		<description><![CDATA[Simple and effective.

PARAM (
	[string] $ZipFilesPath = &#34;X:\Somepath\Full\Of\Zipfiles&#34;,
	[string] $UnzipPath = &#34;X:\Somepath\to\extract\to&#34;
)

$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($UnzipPath)

$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP

$progress = 1
foreach ($ZipFile in $ZipFiles) {
	Write-Progress -Activity &#34;Unzipping to $($UnzipPath)&#34; -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status &#34;File $($Progress) of $($ZipFiles.Count)&#34;
	$ZipFolder = $Shell.NameSpace($ZipFile.fullname)

	$Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes [...]]]></description>
			<content:encoded><![CDATA[<p>Simple and effective.</p>
<pre class="brush: powershell;">
PARAM (
	[string] $ZipFilesPath = &quot;X:\Somepath\Full\Of\Zipfiles&quot;,
	[string] $UnzipPath = &quot;X:\Somepath\to\extract\to&quot;
)

$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($UnzipPath)

$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP

$progress = 1
foreach ($ZipFile in $ZipFiles) {
	Write-Progress -Activity &quot;Unzipping to $($UnzipPath)&quot; -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status &quot;File $($Progress) of $($ZipFiles.Count)&quot;
	$ZipFolder = $Shell.NameSpace($ZipFile.fullname)

	$Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - http://msdn.microsoft.com/en-us/library/bb787866%28VS.85%29.aspx
	$progress++
}
</pre>
<p>Btw&#8230; Watch out&#8230; there is a <strong>-Recurse</strong> on gci&#8230; <img src='http://www.snowland.se/wp/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/06/01/unzip-multiple-files-via-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ACT filling up your disks?</title>
		<link>http://www.snowland.se/2010/04/19/act-filling-up-your-disks/</link>
		<comments>http://www.snowland.se/2010/04/19/act-filling-up-your-disks/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 08:52:52 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[ACT]]></category>
		<category><![CDATA[Disk]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[old]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=459</guid>
		<description><![CDATA[When you have ACT (The Microsoft Application Compatibility Toolkit) running in your environment you might get disks filled up with XML-files on your ACT-server.
The logprocessor uses those files to populate the database with information. So, when those are processed you do not need them anymore. (If you have a backup of your database&#8230;)
So, I did [...]]]></description>
			<content:encoded><![CDATA[<p>When you have ACT (The Microsoft Application Compatibility Toolkit) running in your environment you might get disks filled up with XML-files on your ACT-server.</p>
<p>The logprocessor uses those files to populate the database with information. So, when those are processed you do not need them anymore. (If you have a backup of your database&#8230;)</p>
<p>So, I did it the easy way, scheduled a powershell command to remove files older than 7 days:</p>
<pre class="brush: powershell;">
Get-ChildItem D:\ACTLogs -Recurse -Include *.xml* | where {$_.CreationTime -lt (Get-Date).AddDays(-7)} | Remove-Item
</pre>
<p>If you want a nicer look and feel to your script you can use this instead:</p>
<pre class="brush: powershell;">
Get-ChildItem D:\ACTLogs -Recurse -Include *.xml* | where {$_.CreationTime -lt (Get-Date).AddDays(-7)} | Sort-Object CreationTime | ForEach-Object {
	Write-Host &quot;Processing: &quot; -ForegroundColor Yellow -NoNewline
	Write-Host $_.FullName -ForegroundColor White -NoNewline

	$span = New-TimeSpan $_.CreationTime $(get-date)
	Write-Host &quot; $($span.Days) days old&quot; -ForegroundColor Yellow -NoNewline

	Remove-Item $_.FullName

	Write-Host &quot; [del]&quot; -ForegroundColor Red
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/04/19/act-filling-up-your-disks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manufacturer / Model Collections with hierarchy</title>
		<link>http://www.snowland.se/2010/03/24/manufacturer-model-collections-with-hierarchy/</link>
		<comments>http://www.snowland.se/2010/03/24/manufacturer-model-collections-with-hierarchy/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 08:27:39 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[Hierarchy]]></category>
		<category><![CDATA[Manufacturer]]></category>
		<category><![CDATA[Model]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=434</guid>
		<description><![CDATA[The last post made a flat structure of collections with &#8220;Manufacturer &#8211; Model&#8221;, in this post the script creates a hierarchy with (almost) the same collections.

The Model-collections queries are limited to the parent Manufacturer-collection.

# - - - - - - - - - - - - - - - - - - - - - [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.snowland.se/2010/03/23/manufacturer-model-collections/">last post</a> made a flat structure of collections with &#8220;Manufacturer &#8211; Model&#8221;, in this post the script creates a hierarchy with (almost) the same collections.</p>
<p><img src="http://www.snowland.se/wp/wp-content/uploads/100224_Manufacturer-Model.png" alt="" title="100224_Manufacturer-Model" /><br />
The Model-collections queries are limited to the parent Manufacturer-collection.</p>
<pre class="brush: powershell;">
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#                                                                                                                            Rikard Ronnkvist / snowland.se
#  Usage:
#   Download and install http://www.snowland.se/sccm-posh/
#   Save the file as CreateMM-collections-Hierarchy.ps1
#   PS:&gt;.\CreateMM-collections-Hierarchy.ps1 -rootCollectionName &quot;Name Of Some Collection&quot;
#
#  2010-03-24   Rikard Ronnkvist    First snowland.se release
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PARAM (
	[string] $rootCollectionName = $(throw &quot;rootCollectionName required.&quot;),
	[string] $hostName = (Get-Content env:computername),
	[switch] $Verbose,
	[Switch] $WhatIf
)

if ($verbose.IsPresent) {
	$VerbosePreference = 'Continue'
} Else {
	$VerbosePreference = 'SilentlyContinue'
}

Import-Module SCCM\SCCM-Functions -Force

Write-Verbose &quot;Connect to SCCM-server $($hostName)&quot;
$sccm = Connect-SCCMServer -HostName $hostName

Write-Host &quot;Get root collection: &quot;&quot;$($rootCollectionName)&quot;&quot;&quot;
$rootCollection = Get-SCCMCollection -filter &quot;Name='$($rootCollectionName)'&quot; -sccmserver $sccm
if (!$rootCollection) {
	throw &quot;Cant find &quot;&quot;$($rootCollectionName)&quot;&quot;&quot;
}
Write-Host &quot;Found collection: $($rootCollection.CollectionID)&quot;

Function checkAndCreate ($CollectionName, $ParentCollectionID, $wql, $limit = $null) {
	Write-Host &quot;Checking &quot;&quot;$($CollectionName)&quot;&quot;&quot; -ForegroundColor Cyan
	$newCollection = Get-SCCMCollection -filter &quot;Name='$($CollectionName)'&quot; -sccmserver $sccm

	if (!$newCollection) {
		if (!$WhatIf.IsPresent) {
			Write-Host &quot;Creating collection: &quot;&quot;$($CollectionName)&quot;&quot;&quot;
			$newCollection = New-SCCMCollection -name &quot;$($CollectionName)&quot; -SccmServer $sccm -parentCollectionID $ParentCollectionID -refreshDays 1 -Verbose
		} else {
			Write-Host &quot;What if: Creating collection: &quot;&quot;$($CollectionName)&quot;&quot;&quot; -ForegroundColor Red
		}

		if (!$WhatIf.IsPresent) {
			Write-Verbose &quot;Adding rule with WQL: $wql&quot;
			Add-SCCMCollectionRule -queryExpression $wql -Server $sccm -collectionID $newCollection.CollectionId -queryRuleName $CollectionName -limitToCollectionId $limit
		} else {
			Write-Host &quot;What if: Adding collection rule to new collection with wql: $($wql)&quot; -ForegroundColor Red
		}
	} else {
		Write-Host &quot;Found collection &quot;&quot;$($CollectionName)&quot;&quot;&quot;
	}

	return $newCollection
}

Write-Host &quot;Lookup Manufacturer and Model&quot;
$Manufacturer = Get-wmiobject -query &quot;SELECT DISTINCT Manufacturer FROM SMS_G_System_COMPUTER_SYSTEM&quot; -computername $Sccm.Machine -namespace $Sccm.Namespace | Sort-Object Manufacturer, Model
$Manufacturer | ForEach-Object {
	$wql = &quot;SELECT * FROM SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId where SMS_G_System_COMPUTER_SYSTEM.Manufacturer = '$($_.Manufacturer)'&quot;
	$ManufacturerCollection = checkAndCreate -collectionName $_.Manufacturer -ParentCollectionID $rootCollection.CollectionId -wql $wql -limit $null

	$Model = Get-wmiobject -query &quot;SELECT DISTINCT Model FROM SMS_G_System_COMPUTER_SYSTEM WHERE Manufacturer = '$($ManufacturerCollection.Name)'&quot; -computername $Sccm.Machine -namespace $Sccm.Namespace | Sort-Object Manufacturer, Model
	$Model | ForEach-Object {
		$wql = &quot;SELECT * FROM SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId where SMS_G_System_COMPUTER_SYSTEM.Model = '$($_.Model)'&quot;
		$ModelCollection = checkAndCreate -collectionName $_.Model -ParentCollectionID $ManufacturerCollection.CollectionId -wql $wql -limit $ManufacturerCollection.CollectionId
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/03/24/manufacturer-model-collections-with-hierarchy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manufacturer / Model Collections</title>
		<link>http://www.snowland.se/2010/03/23/manufacturer-model-collections/</link>
		<comments>http://www.snowland.se/2010/03/23/manufacturer-model-collections/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 14:40:11 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[Manufacturer]]></category>
		<category><![CDATA[Model]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=426</guid>
		<description><![CDATA[You have probably created one or two collections that points to a specific Manufacturer and/or Model.
Well, this script will look in to your SCCM-database and create that kind of collections for you.

First you need my SCCM Module for PowerShell
Then I created a collection named &#8220;000 &#8211; Manufacturer &#8211; Model&#8221;
Copy and paste the code below to [...]]]></description>
			<content:encoded><![CDATA[<p>You have probably created one or two collections that points to a specific Manufacturer and/or Model.</p>
<p>Well, this script will look in to your SCCM-database and create that kind of collections for you.</p>
<p><img src="http://www.snowland.se/wp/wp-content/uploads/100223_Manufacturer-Model.png" alt="" title="100223_Manufacturer-Model" /></p>
<p>First you need my <a href="http://www.snowland.se/2010/03/10/sccm-module-for-powershell/">SCCM Module for PowerShell</a><br />
Then I created a collection named &#8220;000 &#8211; Manufacturer &#8211; Model&#8221;<br />
Copy and paste the code below to a file, save it as CreateMM-collections.ps1<br />
Run with at least one param, <strong>-rootCollectionName</strong><br />
<strong>Example:</strong> .\CreateMM-collections.ps1 -rootCollectionName &#8220;000 &#8211; Manufacturer &#8211; Model&#8221;</p>
<p>The script support the <strong>-WhatIf</strong> and <strong>-Verbose</strong> parameters&#8230; might be good to have when testing.</p>
<pre class="brush: powershell;">
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#                                                                                                                            Rikard Ronnkvist / snowland.se
#  Usage:
#   Download and install http://www.snowland.se/sccm-posh/
#   Save the file as CreateMM-collections.ps1
#   PS:&gt;.\CreateMM-collections.ps1 -rootCollectionName &quot;Name Of Some Collection&quot;
#
#  2010-03-23   Rikard Ronnkvist    First snowland.se release
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PARAM (
	[string] $rootCollectionName = $(throw &quot;rootCollectionName required.&quot;),
	[string] $hostName = (Get-Content env:computername),
	[switch] $Verbose,
	[Switch] $WhatIf
)

if ($verbose.IsPresent) {
	$VerbosePreference = 'Continue'
} Else {
	$VerbosePreference = 'SilentlyContinue'
}

Import-Module SCCM\SCCM-Functions -Force

Write-Verbose &quot;Connect to SCCM-server $($hostName)&quot;
$sccm = Connect-SCCMServer -HostName $hostName

Write-Host &quot;Get root collection: &quot;&quot;$($rootCollectionName)&quot;&quot;&quot;
$rootCollection = Get-SCCMCollection -filter &quot;Name='$($rootCollectionName)'&quot; -sccmserver $sccm
if (!$rootCollection) {
	throw &quot;Cant find &quot;&quot;$($rootCollectionName)&quot;&quot;&quot;
}
Write-Host &quot;Found collection: $($rootCollection.CollectionID)&quot;

Write-Host &quot;Lookup Manufacturer and Model&quot;
$ManufacturerModel = Get-wmiobject -query &quot;SELECT DISTINCT Manufacturer, Model FROM SMS_G_System_COMPUTER_SYSTEM&quot; -computername $Sccm.Machine -namespace $Sccm.Namespace | Sort-Object Manufacturer, Model
$ManufacturerModel | ForEach-Object {
	$mmCollectionName = &quot;$($_.Manufacturer) - $($_.Model)&quot;
	Write-Host &quot;Checking &quot;&quot;$($mmCollectionName)&quot;&quot;&quot; -ForegroundColor Cyan

	$mmCollection = Get-SCCMCollection -filter &quot;Name='$($mmCollectionName)'&quot; -sccmserver $sccm

	if (!$mmCollection) {
		if (!$WhatIf.IsPresent) {
			Write-Host &quot;Creating collection: &quot;&quot;$($mmCollectionName)&quot;&quot;&quot;
			$newMmCollection = New-SCCMCollection -name &quot;$($mmCollectionName)&quot; -SccmServer $sccm -parentCollectionID $rootCollection.CollectionID -refreshDays 1
		} else {
			Write-Host &quot;What if: Creating collection: &quot;&quot;$($mmCollectionName)&quot;&quot;&quot; -ForegroundColor Red
		}

		$wql = &quot;SELECT * FROM SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId where SMS_G_System_COMPUTER_SYSTEM.Manufacturer = '$($_.Manufacturer)'  AND SMS_G_System_COMPUTER_SYSTEM.Model = '$($_.Model)'&quot;
		if (!$WhatIf.IsPresent) {
			Write-Verbose &quot;Adding rule with WQL: $wql&quot;
			Add-SCCMCollectionRule -queryExpression $wql -Server $sccm -collectionID $newMmCollection.CollectionId -queryRuleName $mmCollectionName
		} else {
			Write-Host &quot;What if: Adding collection rule to new collection with wql: $($wql)&quot; -ForegroundColor Red
		}
	} else {
		Write-Host &quot;Found collection&quot;
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/03/23/manufacturer-model-collections/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SCCM Module for PowerShell</title>
		<link>http://www.snowland.se/2010/03/10/sccm-module-for-powershell/</link>
		<comments>http://www.snowland.se/2010/03/10/sccm-module-for-powershell/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 13:44:14 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Commands]]></category>
		<category><![CDATA[Module]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=421</guid>
		<description><![CDATA[In a post a few days ago I mentioned &#8220;some slightly modified functions from Michael Niehaus&#8220;.
Well&#8230; Why not share them.
Save this as a module, load it and play around.
2010-03-26 &#8211; Moved to http://www.snowland.se/sccm-posh/
Some examples on what you can do:

# List all available SCCM commands
Get-SCCMCommands

# Create an SCCM-Connection to the local server
$sccm = Connect-SCCMServer -Verbose

# Create [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.snowland.se/2010/03/05/add-text-to-images-with-powershell/">a post a few days ago</a> I mentioned &#8220;some slightly modified functions from <a href="http://blogs.technet.com/mniehaus/archive/2009/04/07/fun-with-configmgr-2007-and-powershell.aspx">Michael Niehaus</a>&#8220;.</p>
<p>Well&#8230; Why not share them.</p>
<p>Save this as a module, load it and play around.</p>
<h2>2010-03-26 &#8211; Moved to <a href="http://www.snowland.se/sccm-posh/">http://www.snowland.se/sccm-posh/</a></h2>
<p><strong>Some examples on what you can do:</strong></p>
<pre class="brush: powershell;">
# List all available SCCM commands
Get-SCCMCommands

# Create an SCCM-Connection to the local server
$sccm = Connect-SCCMServer -Verbose

# Create a new collection with a collection rule
$newCollection = New-SCCMCollection -SccmServer $sccm -name &quot;Some Collection Name&quot; -Verbose
Add-SCCMCollectionRule -Server $sccm -collectionID $newRoot.CollectionId -queryExpression &quot;SELECT * FROM SMS_R_System&quot; -queryRuleName &quot;All Systems&quot; -Verbose

# Count files in the inboxes
$sccm | Get-SCCMInboxes

# Get a package
$MyPackage = Get-SCCMPackage -server $sccm -filter &quot;Name = 'Some Package Name'&quot;
</pre>
<p>If you have some comments, ideas and things to add&#8230; Comment this post or shoot me an <a href="mailto:rikard@ronnkvist.nu">email</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/03/10/sccm-module-for-powershell/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Add text to images with PowerShell</title>
		<link>http://www.snowland.se/2010/03/05/add-text-to-images-with-powershell/</link>
		<comments>http://www.snowland.se/2010/03/05/add-text-to-images-with-powershell/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 12:19:17 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[BootImage]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Text]]></category>
		<category><![CDATA[WinPE]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=411</guid>
		<description><![CDATA[Been working on some server deployment lately and had some problems with the WinPE&#8230; so to not get to confused when using different PE&#8217;s to boot up the servers we added some image-information on the background.
Did that in MS Paint&#8230; but how fun is that?  
Here is a cool function that add some text [...]]]></description>
			<content:encoded><![CDATA[<p>Been working on some server deployment lately and had some problems with the WinPE&#8230; so to not get to confused when using different PE&#8217;s to boot up the servers we added some image-information on the background.</p>
<p>Did that in MS Paint&#8230; but how fun is that? <img src='http://www.snowland.se/wp/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p>Here is a cool function that add some text to a image (Original code from <a href="http://www.ravichaganti.com/blog/?p=1012">http://www.ravichaganti.com/blog/?p=1012</a>)</p>
<pre class="brush: powershell;">
Function AddTextToImage {
	# Orignal code from http://www.ravichaganti.com/blog/?p=1012
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true)][String] $sourcePath,
		[Parameter(Mandatory=$true)][String] $destPath,
		[Parameter(Mandatory=$true)][String] $Title,
		[Parameter()][String] $Description = $null
	)

	Write-Verbose &quot;Load System.Drawing&quot;
	[Reflection.Assembly]::LoadWithPartialName(&quot;System.Drawing&quot;) | Out-Null

	Write-Verbose &quot;Get the image from $sourcePath&quot;
	$srcImg = [System.Drawing.Image]::FromFile($sourcePath)

	Write-Verbose &quot;Create a bitmap as $destPath&quot;
	$bmpFile = new-object System.Drawing.Bitmap([int]($srcImg.width)),([int]($srcImg.height))

	Write-Verbose &quot;Intialize Graphics&quot;
	$Image = [System.Drawing.Graphics]::FromImage($bmpFile)
	$Image.SmoothingMode = &quot;AntiAlias&quot;

	$Rectangle = New-Object Drawing.Rectangle 0, 0, $srcImg.Width, $srcImg.Height
	$Image.DrawImage($srcImg, $Rectangle, 0, 0, $srcImg.Width, $srcImg.Height, ([Drawing.GraphicsUnit]::Pixel))

	Write-Verbose &quot;Draw title: $Title&quot;
	$Font = new-object System.Drawing.Font(&quot;Verdana&quot;, 24)
	$Brush = New-Object Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(255, 0, 0,0))
	$Image.DrawString($Title, $Font, $Brush, 10, 10)

	if ($Description -ne $null) {
		Write-Verbose &quot;Draw description: $Description&quot;
		$Font = New-object System.Drawing.Font(&quot;Verdana&quot;, 12)
		$Brush = New-Object Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(120, 0, 0, 0))
		$Image.DrawString($Description, $Font, $Brush, 10, 50)
	}

	Write-Verbose &quot;Save and close the files&quot;
	$bmpFile.save($destPath, [System.Drawing.Imaging.ImageFormat]::Bmp)
	$bmpFile.Dispose()
	$srcImg.Dispose()
}
</pre>
<p>With that piece of code and some slightly modified functions from <a href="http://blogs.technet.com/mniehaus/archive/2009/04/07/fun-with-configmgr-2007-and-powershell.aspx">Michael Niehaus</a> you can do some cool stuff&#8230;</p>
<pre class="brush: powershell;">
$taskSequence = &quot;Server Deployment Task Sequence&quot;

Import-Module Misc\Image-Functions.psm1
Import-Module SCCM\SCCM-Functions.psm1

$sccm = Connect-SCCMServer
$taskSequence = Get-TaskSequencePackage -SccmServer $sccm -filter &quot;Name = '$taskSequence'&quot;
$BootImage = Get-BootImagePackage -SccmServer $sccm -filter &quot;PackageID = '$($taskSequence.BootImageID)'&quot;
$DescriptionText = &quot;Version:`t$($BootImage.Version)`nPackageID:`t$($BootImage.PackageID)`n`n$($BootImage.Description)&quot;

AddTextToImage -sourcePath &quot;X:\Path\WinPE-Background-Source.bmp&quot; -destPath &quot;X:\Path\WinPE-Background-To-Inject.bmp&quot; -Title $BootImage.Name -Description $DescriptionText
</pre>
<p>Shouldn&#8217;t be that hard to auto-inject the BMP to the WIM file&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/03/05/add-text-to-images-with-powershell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nice PowerShell prompt</title>
		<link>http://www.snowland.se/2010/02/23/nice-powershell-prompt/</link>
		<comments>http://www.snowland.se/2010/02/23/nice-powershell-prompt/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 07:00:47 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[Good-to-have]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Prompt]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=407</guid>
		<description><![CDATA[Been playing around with PowerShell the last days, and with nothing else better to do I did a nice looking prompt.  

This prompt will give you a marker if you run it as Administrator and another mark if you are outside the filesystem.
How to:
First you need to edit your profile so it autoload the [...]]]></description>
			<content:encoded><![CDATA[<p>Been playing around with PowerShell the last days, and with nothing else better to do I did a nice looking prompt. <img src='http://www.snowland.se/wp/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><img src="http://www.snowland.se/wp/wp-content/uploads/100223_PowershellPrompt.png" alt="" title="100223_PowershellPrompt"  /></p>
<p>This prompt will give you a marker if you run it as Administrator and another mark if you are outside the filesystem.</p>
<p><strong>How to:</strong><br />
First you need to edit your profile so it autoload the new prompt.</p>
<pre class="brush: powershell;">
notepad $profile
</pre>
<p>Then paste this code, save and start a new PowerShell command line.</p>
<pre class="brush: powershell;">
function prompt
{
	# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	#                                                                              Rikard Ronnkvist / snowland.se
	# Multicolored prompt with marker for windows started as Admin and marker for providers outside filesystem
	# Examples
	#    C:\Windows\System32&gt;
	#    [Admin] C:\Windows\System32&gt;
	#    [Registry] HKLM:\SOFTWARE\Microsoft\Windows&gt;
	#    [Admin] [Registry] HKLM:\SOFTWARE\Microsoft\Windows&gt;
	# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	# New nice WindowTitle
	$Host.UI.RawUI.WindowTitle = &quot;PowerShell v&quot; + (get-host).Version.Major + &quot;.&quot; + (get-host).Version.Minor + &quot; (&quot; + $pwd.Provider.Name + &quot;) &quot; + $pwd.Path

	# Admin ?
	if( (
		New-Object Security.Principal.WindowsPrincipal (
			[Security.Principal.WindowsIdentity]::GetCurrent())
		).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
	{
		# Admin-mark in WindowTitle
		$Host.UI.RawUI.WindowTitle = &quot;[Admin] &quot; + $Host.UI.RawUI.WindowTitle

		# Admin-mark on prompt
		Write-Host &quot;[&quot; -nonewline -foregroundcolor DarkGray
		Write-Host &quot;Admin&quot; -nonewline -foregroundcolor Red
		Write-Host &quot;] &quot; -nonewline -foregroundcolor DarkGray
	}

	# Show providername if you are outside FileSystem
	if ($pwd.Provider.Name -ne &quot;FileSystem&quot;) {
		Write-Host &quot;[&quot; -nonewline -foregroundcolor DarkGray
		Write-Host $pwd.Provider.Name -nonewline -foregroundcolor Gray
		Write-Host &quot;] &quot; -nonewline -foregroundcolor DarkGray
	}

	# Split path and write \ in a gray
	$pwd.Path.Split(&quot;\&quot;) | foreach {
	    Write-Host $_ -nonewline -foregroundcolor Yellow
	    Write-Host &quot;\&quot; -nonewline -foregroundcolor Gray
	}

	# Backspace last \ and write &gt;
	Write-Host &quot;`b&gt;&quot; -nonewline -foregroundcolor Gray

    return &quot; &quot;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/02/23/nice-powershell-prompt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Read MSI information with PowerShell</title>
		<link>http://www.snowland.se/2010/02/21/read-msi-information-with-powershell/</link>
		<comments>http://www.snowland.se/2010/02/21/read-msi-information-with-powershell/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 10:45:04 +0000</pubDate>
		<dc:creator>riro</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[COM+]]></category>
		<category><![CDATA[MSI]]></category>

		<guid isPermaLink="false">http://www.snowland.se/?p=404</guid>
		<description><![CDATA[I tried to search for some way to read MSI-information with PowerShell, that wasn&#8217;t to easy to find.
Anyway, here is a function that helps you read the &#8220;Property&#8221; view from one MSI-file, the result is stored in a hash table.

# Load some TypeData
$SavedEA = $Global:ErrorActionPreference
$Global:ErrorActionPreference = &#34;SilentlyContinue&#34;
Update-TypeData -AppendPath ((Split-Path -Parent $MyInvocation.MyCommand.Path) + &#34;\comObject.types.ps1xml&#34;)
$Global:ErrorActionPreference = $SavedEA

function [...]]]></description>
			<content:encoded><![CDATA[<p>I tried to search for some way to read MSI-information with PowerShell, that wasn&#8217;t to easy to find.</p>
<p>Anyway, here is a function that helps you read the &#8220;Property&#8221; view from one MSI-file, the result is stored in a hash table.</p>
<pre class="brush: powershell;">
# Load some TypeData
$SavedEA = $Global:ErrorActionPreference
$Global:ErrorActionPreference = &quot;SilentlyContinue&quot;
Update-TypeData -AppendPath ((Split-Path -Parent $MyInvocation.MyCommand.Path) + &quot;\comObject.types.ps1xml&quot;)
$Global:ErrorActionPreference = $SavedEA

function global:get-msiproperties {
	PARAM (
		[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,HelpMessage=&quot;MSI Database Filename&quot;,ValueFromPipeline=$true)]
		[Alias(&quot;Filename&quot;,&quot;Path&quot;,&quot;Database&quot;,&quot;Msi&quot;)]
		$msiDbName
	)

	# A quick check to see if the file exist
	if(!(Test-Path $msiDbName)){
		throw &quot;Could not find &quot; + $msiDbName
	}

	# Create an empty hashtable to store properties in
	$msiProps = @{}

	# Creating WI object and load MSI database
	$wiObject = New-Object -com WindowsInstaller.Installer
	$wiDatabase = $wiObject.InvokeMethod(&quot;OpenDatabase&quot;, (Resolve-Path $msiDbName).Path, 0)

	# Open the Property-view
	$view = $wiDatabase.InvokeMethod(&quot;OpenView&quot;, &quot;SELECT * FROM Property&quot;)
	$view.InvokeMethod(&quot;Execute&quot;)

	# Loop thru the table
	$r = $view.InvokeMethod(&quot;Fetch&quot;)
	while($r -ne $null) {
		# Add property and value to hash table
		$msiProps[$r.InvokeParamProperty(&quot;StringData&quot;,1)] = $r.InvokeParamProperty(&quot;StringData&quot;,2)

		# Fetch the next row
		$r = $view.InvokeMethod(&quot;Fetch&quot;)
	}

	$view.InvokeMethod(&quot;Close&quot;)

	# Return the hash table
	return $msiProps
}
</pre>
<p>You need to expand your type configuration with this file, saved as <strong>comObject.types.ps1xml</strong> in the same directory as the script above.</p>
<pre class="brush: xml;">
&lt;!--
Copy from: Abhishek's PowerShell Blog - http://abhishek225.spaces.live.com/blog/

Original post: http://abhishek225.spaces.live.com/blog/cns!13469C7B7CE6E911!165.entry
--&gt;
&lt;Types&gt;
	&lt;Type&gt;
		&lt;Name&gt;System.__ComObject&lt;/Name&gt;
		&lt;Members&gt;
			&lt;ScriptMethod&gt;
				&lt;Name&gt;GetProperty&lt;/Name&gt;
				&lt;Script&gt;
					$type = $this.gettype();
					$type.invokeMember($args[0],[System.Reflection.BindingFlags]::GetProperty,$null,$this,$null)
				&lt;/Script&gt;
			&lt;/ScriptMethod&gt;
			&lt;ScriptMethod&gt;
				&lt;Name&gt;SetProperty&lt;/Name&gt;
				&lt;Script&gt;
					$type = $this.gettype();
					$type.invokeMember($args[0],[System.Reflection.BindingFlags]::GetProperty,$null,$this,@($args[1]))
				&lt;/Script&gt;
			&lt;/ScriptMethod&gt;
			&lt;ScriptMethod&gt;
				&lt;Name&gt;InvokeParamProperty&lt;/Name&gt;
				&lt;Script&gt;
					$type = $this.gettype();
					$index = $args.count -1 ;
					$methodargs=$args[1..$index]
					$type.invokeMember($args[0],[System.Reflection.BindingFlags]::GetProperty,$null,$this,$methodargs)
				&lt;/Script&gt;
			&lt;/ScriptMethod&gt;
			&lt;ScriptMethod&gt;
				&lt;Name&gt;InvokeMethod&lt;/Name&gt;
				&lt;Script&gt;
					$type = $this.gettype();
					$index = $args.count -1 ;
					$methodargs=$args[1..$index]
					$type.invokeMember($args[0],[System.Reflection.BindingFlags]::InvokeMethod,$null,$this,$methodargs)
				&lt;/Script&gt;
			&lt;/ScriptMethod&gt;
		&lt;/Members&gt;
	&lt;/Type&gt;
&lt;/Types&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.snowland.se/2010/02/21/read-msi-information-with-powershell/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
