Trevor Sullivan's Tech Room

Minding the gap between administration and development

Archive for the ‘tools’ Category

PowerShell: Prompt Function to Monitor Memory Usage

Posted by Trevor Sullivan on 2012/01/23


Have you ever wanted to monitor your memory utilization in a PowerShell instance, but may not want to continually issue commands to determine it? Introducing …… the PowerShell Prompt to monitor memory utilization!!

function prompt {
    "$('{0:n2}' -f ([double](Get-Process -Id $pid).WorkingSet/1MB)) MB> "
}

Here’s the result:

image

Posted in powershell, tools | Tagged: , , , , , , | 1 Comment »

PowerShell: Move ConfigMgr Collections

Posted by Trevor Sullivan on 2012/01/12


Introduction

If you work with Microsoft System Center Configuration Manager (SCCM / ConfigMgr) 2007 in any capacity, you probably are familiar with the concept of "collections" and how painful they can be to work with sometimes. The ConfigMgr console does not provide any method of moving a collection from one parent to another, and the GUI is pretty slow to work with.

image

So what’s the solution here? PowerShell, of course!

PowerShell Code

Here is a PowerShell function that will allow you to move a ConfigMgr collection either by name or by collection ID.

Note: Select all of the function text top-to-bottom, and you can retrieve the text that is cut off towards the right.

<#
    .Synopsis
    This function allows you to re-assing the parent for a ConfigMgr collection to a new collection ID

    .Author
    Trevor Sullivan (pcgeek86@gmail.com)

    .Example
    c:\PS> Move-SccmCollection -SccmServer sccm01 -SiteCode LAB -CollectionID LAB00159 -ParentCollectionID LAB000150;

    Description
    -----------

    This command moves the ConfigMgr collection with ID "LAB000159" to being a child of collection ID "LAB000150".

    .Example
    c:\PS> Move-SccmCollection -SccmServer sccm01 -SiteCode LAB -CollectionName 'Visual Studio' -ParentCollectionID Microsoft;

    Description
    -----------

    This command moves the ConfigMgr collection named "Visual Studio" to being a child of the collection named "Microsoft". Note that you do not need to specify quotes around the parameter value if it does not contain spaces.

    .Notes
    This function is untested with collection links. It is not known whether or not this will remove existing collection links.
#>
function Move-SccmCollection {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)] [string] ${SccmServer}
        , [Parameter(Mandatory = $true)] [string] ${SiteCode}
        , [Parameter(ParameterSetName = "ByCollectionID", Mandatory = $true)] [string] ${CollectionID}
        , [Parameter(ParameterSetName = "ByCollectionID", Mandatory = $true)] [string] ${ParentCollectionID}
        , [Parameter(ParameterSetName = "ByCollectionName", Mandatory = $true)] [string] ${CollectionName}
        , [Parameter(ParameterSetName = "ByCollectionName", Mandatory = $true)] [string] ${ParentCollectionName}
    )

    # Set-PSDebug -Strict;

    # Ensure that ConfigMgr site server is available
    if (-not (Test-Connection -ComputerName $SccmServer -Count 1)) {
        return;
    }

    # Obtain references to collection and parent collection
    switch ($PSCmdlet.ParameterSetName) {
        # Use the "ByCollectionID" PowerShell parameter set to retrieve collection references by ID
        'ByCollectionID' {
            ${CollectionRelationship} = @(Get-WmiObject -ComputerName $SccmServer -Namespace root\sms\site_$SiteCode -Class SMS_CollectToSubCollect -Filter "subCollectionID = '$CollectionID'")[0];
            ${Collection} = @([wmi]("\\{0}\root\sms\site_{1}:SMS_Collection.CollectionID='{2}'" -f ${SccmServer}, ${SiteCode}, ${CollectionID}))[0];
            ${ParentCollection} = @([wmi]("\\{0}\root\sms\site_{1}:SMS_Collection.CollectionID='{2}'" -f ${SccmServer}, ${SiteCode}, ${ParentCollectionID}))[0];
        }
        # Use the "ByCollectionName" PowerShell parameter set to retrieve collection references by name
        'ByCollectionName' {
            ${Collection} = [wmi](@(Get-WmiObject -ComputerName $SccmServer -Namespace root\sms\site_$SiteCode -Class SMS_Collection -Filter ("Name = '{0}'" -f ${CollectionName}))[0].__PATH);
            ${ParentCollection} = [wmi](@(Get-WmiObject -ComputerName $SccmServer -Namespace root\sms\site_$SiteCode -Class SMS_Collection -Filter ("Name = '{0}'" -f ${ParentCollectionName}))[0].__PATH);
            ${CollectionRelationship} = @(Get-WmiObject -ComputerName $SccmServer -Namespace root\sms\site_$SiteCode -Class SMS_CollectToSubCollect -Filter ("subCollectionID = '{0}'" -f ${Collection}.CollectionID))[0];
        }
    } 
    
    # If references to both the child and [new] parent collection were obtained, then move on
    if (${Collection} -and ${ParentCollection}) {
        Write-Verbose -Message ('Setting parent collection for {0}:{1} to {2}:{3}' -f `
            ${Collection}.CollectionID `
            , ${Collection}.Name `
            , ${ParentCollection}.CollectionID `
            , ${ParentCollection}.Name);
        ${CollectionRelationship}.parentCollectionID = ${ParentCollection}.CollectionID;
        # Create the new collection relationship (this [oddly] spawns a NEW instance of SMS_CollectToSubCollect), so we have to clean up the original one
        ${CollectionRelationship}.Put();

        # Clean up all other collection relantionships for this collection
        ${OldCollectionRelationshipList} = @(Get-WmiObject -ComputerName $SccmServer -Namespace root\sms\site_$SiteCode -Class SMS_CollectToSubCollect -Filter ("subCollectionID = '{0}' and parentCollectionID <> '{1}'" -f ${Collection}.CollectionID, ${ParentCollection}.CollectionID));
        foreach (${OldCollectionRelationship} in ${OldCollectionRelationshipList}) {
            ${OldCollectionRelationship}.Delete();
        }
    }
    else {
        Write-Warning -Message 'Please ensure that you have entered a valid collection ID or name';
    }
}

 

Here is an example of how to use this function to move a collection based on their collection IDs:

Move-SccmCollection -SccmServer sccm01.mybiz.loc -SiteCode LAB -CollectionID LAB00011 -ParentCollectionID LAB00022;

Here is an example of how to use the function to move a collection based on the collection name:

Move-SccmCollection -SccmServer sccm01.mybiz.loc -SiteCode LAB -CollectionName ‘Visual Studio’ -ParentCollectionID Microsoft;

Posted in configmgr, powershell, scripting, tools, wmi | Tagged: , , , , , , , , , , , , , , , , | Leave a Comment »

PowerShell: PowerEvents Module Update to 0.3 Alpha

Posted by Trevor Sullivan on 2012/01/11


imageIf you haven’t already checked it out, I wrote and published a PowerShell module on CodePlex a little over a year ago. It’s called PowerEvents for Windows PowerShell, and allows you to easily work with permanent WMI (Windows Management Instrumentation) event subscriptions. Some folks may not be aware that I’ve also written comprehensive documentation on the theory behind WMI events and why they’re useful. This ~30-page PDF document is included in the PowerEvents download, and is useful even if you do not want to use the PowerEvents module.

As a bonus, the PowerEvents module was mentioned just recently in the PowerScripting Podcast (listen around 1h19m)!!

http://powerscripting.wordpress.com/2012/01/09/episode-171-listener-call-in/

Listen to my interview with the PowerScripting Podcast back in December 2010!

http://powerscripting.wordpress.com/2010/12/13/episode-134-trevor-sullivan-on-wmi-events-in-powershell/

PowerEvents Download Link: http://powerevents.codeplex.com/

Posted in powershell, scripting, tools, wmi | Tagged: , , , , , , , , | 1 Comment »

PowerShell: List Strongly Typed Names in Global Assembly Cache

Posted by Trevor Sullivan on 2011/12/30


I dislike using deprecated commands or APIs when I know that there’s a more modern method of performing an action. I also generally prefer to use Windows PowerShell as a .NET scripting language, rather than constantly relying on cmdlets. To be sure, I use a balance of both concepts, since cmdlets can save a whole lot of coding a lot of the time.

Every time I want to load an assembly into PowerShell, the first thing that pops into my mind is:

[Reflection.Assembly]::LoadWithPartialName();

Unfortunately Microsoft recommends against using that static method, and recommends use of other methods like:

[Reflection.Assembly]::Load(StronglyTypedAssemblyName);

In the interest of not breaking my conscience, I would like to use this method, but the problem then becomes that I have to constantly figure out what the strongly-typed name of the assembly I want is. To help solve this problem, I decided to write a PowerShell script that extracts information from the .NET assemblies in the Global Assembly Cache (GAC), since those are generally the most common ones I’ll need to reference.

Read the rest of this entry »

Posted in .NET, powershell, scripting, tools | Tagged: , , , , , , , | 6 Comments »

Checking Status of a Windows 7 System Image

Posted by Trevor Sullivan on 2011/12/30


If you’re running Windows 7, you may periodically create a “System Image” which is essentially just a VHD backup of your system. When you invoke the task, you will be presented with a dialog box similar to the following, which shows the progress of the backup:

image

If you are scripting something, and want your script to proceed when the backup has completed, you can run this command line:

wbadmin.exe get status

This program will "block" (continue running) and report progress, as a percentage, until the backup has completed.

image

Posted in tools | Tagged: , , , , , , , | Leave a Comment »

HP ProLiant DL360 G7 Video Driver

Posted by Trevor Sullivan on 2011/12/16


I was looking for a video driver for the HP ProLiant DL360 G7 so I could import it into ConfigMgr for the purposes of deploying Windows Server 2008 R2 to them. Oddly enough, HP doesn’t list a video driver available for download on the driver download page for this system model. On one server, I noticed that the device name was "ATI ES1000,” and most of you are probably aware that the ATI brand name has been gone for some time, so this seemed a bit odd.

Read the rest of this entry »

Posted in configmgr, OSD, tools | Tagged: , , , , , , , , , , | Leave a Comment »

PowerShell: Override GPO and Detect Windows Updates

Posted by Trevor Sullivan on 2011/12/14


Introduction

If you’re using a workstation in an enterprise environment, there may be Active Directory Group Policy Object (GPO) settings forcing a certain behavior of the Microsoft Windows Update Agent (aka. Automatic Update Agent). You might be a power user who wants to actually ensure that their workstation is fully patched before the IT department releases patches according to their standard cycle. One option would be to ask your IT department to include you in the pilot group for software updates, but failing that option, you can temporarily override the GPO settings and force an updates detection.

Read the rest of this entry »

Posted in powershell, scripting, tools | Tagged: , , , , | Leave a Comment »

ConfigMgr: Cleanup Software Updates Objects

Posted by Trevor Sullivan on 2011/11/29


Introduction

A common complaint I hear about Microsoft System Center Configuration Manager (SCCM / ConfigMgr) 2007 is the ability to clean up expired and superseded software updates from the objects related to software updates. As software updates are marked as expired or are superseded by newer software updates, Microsoft marks the old updates accordingly. Once an update has been retired, it is desirable for ConfigMgr administrators to remove the updates from deployments and reporting objects. This cleanup effort saves disk space for deployment packages, and can reduce unnecessary information from showing up in reports.

Read the rest of this entry »

Posted in configmgr, powershell, scripting, tools, wmi | Tagged: , , , , , , , , , , , , | Leave a Comment »

Microsoft Assessment and Planning Toolkit 6.0: Task Processor Busy

Posted by Trevor Sullivan on 2011/11/23


If you install the Microsoft Assessment and Planning (MAP) Toolkit 6.0, and you run a large inventory job, you may find that it takes a long time to complete. If you have hidden the inventory status window, the MAP console will provide limited functionality until the inventory process is completed. Attempting to perform certain console functions may yield the following error message:

The task processor is currently busy. You cannot perform this operation while the task processor is running. Please wait for the task processor to complete or cancel the task processor before retrying this operation.

image

There isn’t any menu option to simply stop the task processor, so you’ll need to choose File –> Exit, which will prompt you to stop it.

image

Posted in fixes, tools | Tagged: , , , , , , | Leave a Comment »

PowerShell / ConfigMgr: Count of Client Manufacturer / Models

Posted by Trevor Sullivan on 2011/11/09


Introduction

If you’re an administrator of Microsoft System Center Configuration Manager (SCCM / ConfigMgr) 2007, you might be interested in finding out what make / model of client & server systems you have, and how many of each unique value you have. Most people would probably simply pull up a ConfigMgr report, but did you know that there’s an automated way to get this information as well?

Using PowerShell

You’ll need the following to execute this simple script:

  • A user account with access to the ConfigMgr provider
  • The hostname of the ConfigMgr central site server
  • The site code of the ConfigMgr central site

Once you’ve launched PowerShell under the appropriate account’s credentials, simply run this command:

Clear-Host

$ComputerSystems = Get-WmiObject `
    -Namespace root\sms\site_000 `
    -ComputerName sccm01.mydomain.com `
    -Class SMS_G_System_Computer_System

$ComputerSystems `
    | Group-Object -Property Manufacturer,Model `
    | Where-Object { $_.Count -gt 5 } `
    | Sort-Object -Property Count -Descending

If you get an error saying "An empty pipe element is not allowed" then make sure that there is not a space after one of the backticks. The backtick is the continuation character, and tells PowerShell to keep processing the command on the next line, and if there is a space after it, the interpreter will get confused.

If everything works as expected, you should see output similar to the following:

Count Name                    
—– —-                    
  222 Dell Inc., OptiPlex 780 
  136 Dell Inc., OptiPlex GX620

  135 Dell Inc., OptiPlex 755 
  134 Dell Inc., OptiPlex 745 
  101 Dell Inc., OptiPlex GX280

There will also be a “group” property, which contains the actual .NET objects that were grouped into each line item.

Hope this helps!

Posted in configmgr, powershell, scripting, tools, wmi | Tagged: , , , , , , , , , , , , | Leave a Comment »