Antivirus exclusions for ConfigMgr

Big thanks to my MVP colleague Peter Daalmans for his post on antivirus exclusions for ConfigMgr.

 

Check out his very thorough post on Anti-virus scan exclusions for Configuration Manager 2012.

Attend the CloudOS Signature Events

Get hands-on with the new technology, and learn how to manage and build your modern data center with the Microsoft Cloud OS platform: Windows Server 2012, Windows Azure, Visual Studio 2012 and System Center 2012

Register Here: http://www.microsoft.com/enterprise/events/signature/#fbid=TOp6OyNDKdZ

     Can’t make the launch in person, then join us online (Sept 4th, 8:00AM): http://www.microsoft.com/en-us/server-cloud/new.aspx

Server 2012 Jump Start series on TechNet

How To: Display all Methods for All Classes in a WMI Namespace using PowerShell

Yes, that title is a bit cryptic – if you’ve worked a bit in WMI with PowerShell, you’ll see this code and (hopefully) think “Cool.” If you’re new to PowerShell and/or WMI, well, hang on to your hat, we’ll start diving into these soon to see how we can use them.

This example command displays all methods under the root\ccm\clientsdk namespace – this is a namespace that you will find on all ConfigMgr 2012 clients.

get-wmiobject -namespace root\ccm\clientsdk -list | select __Path -Expand Methods | select Origin, Name, __Path | out-gridview

Greg

How to: Query MachineOU information from ConfigMgr using PowerShell

With the Application Model in ConfigMgr 2012, you can create requirement rules based on Machine OU. Here’s a quick script to see what the ConfigMgr 2012 client has stored as the Machine OU:

( gwmi global_machineOU -namespace root\ccm\cimodels).MachineOU

Happy Scripting!

Greg

ramseyg@hotmail.com

How to: Exectue a ConfigMgr 2012 Auto Deployment Rule (ADR)

Here’s a quick example for how to initiate an ADR using PowerShell:

(gwmi sms_autodeployment -namespace root\sms\site_cas -computer MyServer -filter "Name='FEP Updates'").EvaluateAutoDeployment()

Replace CAS with your site code, and MyServer with the server name. My ADR is “FEP Updates”, so replace that with the desired ADR to run. Remember that ADRs are dependent on the WSUS synchronization, so if you re-evaluate the ADR without a new WSUS synchronization, you may not see any change in your ADR.

If you really want to party, and desire to re-run all ADRs, run the following command:

gwmi sms_autodeployment -namespace root\sms\site_cas -computer MyServer | foreach-object {$_.EvaluateAutoDeployment()}

This will find all ADRs, and call the EvaluateAutoDeployment method on each one.
Happy Scripting,

Greg

ramseyg@hotmail.com

How To: Enable Defrag on Server 2008R2 and Windows 7 Using ConfigMgr Setttings Management

We found several systems recently where defrag was not enabled. Thanks to a little help from the TechNet forums, I was able to create a Compliance Settings Rule using PowerShell. Create a new compliance settings configuration item as follows:

      1. Choose a name (Such as Enable Defrag).
      2. Choose the supported platforms (all Windows 7, all Server 2008 R2)
      3. Create a new Setting, choose Script for the setting type, and Boolean for the data type.
      4. Paste the PowerShell code below for the Discovery Script:
        # Used by the RegisterTaskDefinition method
        $TASK_CREATE_OR_UPDATE = 0x6
        
        # Specify the computer name
        $computerName = "localhost"
        # Specify the task's name
        $taskName = "\Microsoft\Windows\Defrag\ScheduledDefrag"
        
        $taskService = new-object -comobject "Schedule.Service"
        $taskService.Connect($computerName)
        $taskFolder = $taskService.GetFolder("\")
        $registeredTask = $taskFolder.GetTask($taskName)
        $registeredTask.Enabled = $TRUE
        $taskDefinition = $registeredTask.Definition
        $taskDefinition.Triggers | % {$_.Enabled}
        
      5. Paste the PowerShell code below for the Remediation Script.
        $TASK_CREATE_OR_UPDATE = 0x6
        
        # Specify the computer name
        $computerName = "localhost"
        # Specify the task's name
        $taskName = "\Microsoft\Windows\Defrag\ScheduledDefrag"
        
        $taskService = new-object -comobject "Schedule.Service"
        $taskService.Connect($computerName)
        $taskFolder = $taskService.GetFolder("\")
        $registeredTask = $taskFolder.GetTask($taskName)
        $registeredTask.Enabled = $TRUE
        $taskDefinition = $registeredTask.Definition
        $taskDefinition.Triggers | foreach-object { $_.Enabled = $TRUE }
        [Void] $taskFolder.RegisterTaskDefinition($taskName, $taskDefinition,
         $TASK_CREATE_OR_UPDATE, $NULL, $NULL, $taskDefinition.Principal.LogonType)
        
      6. Create a new Compliance Rule tab of the configuration item, where Enabled = True, as shown next:
      7. Add this configuration item to a baseline and deploy to a collection. Note that in order to  execute Compliance Management scripts that use Powershell, you may need to modify the client setting named “PowerShell Execution Policy”  to Bypass.

Download EnableDefragOnServer08andWindows7.ps1.


How To: Create A Collection for Each AD Site in the Current Forest

Here’s an example of leveraging PowerShell to query AD to find all Active Directory Sites, and then create a collection for each one (unless it already exists) in ConfigMgr 2012:

#update Site Server and Namespace information for SMS Provider
$Server = "myServer"
$NameSpace = "root\sms\site_LAB"
#enter collectionID that will be used as the limiting collection for the new collections.
$CollectionLimiter = "LAB00018"

function CreateCollectionQueryRule($Coll, $Server, $Namespace, $RuleName, $WQL)
{
#function used to create the rule for the query, based on QueryID.
$wmiclass = "\\" + $Server + "\" + $NameSpace + ":sms_CollectionRuleQuery"
$wmiclass
$CollQuery = ([wmiclass] $wmiclass).CreateInstance()
$collquery.QueryExpression = $WQL
$CollQuery.RuleName = $RuleName
$coll = gwmi sms_collection -namespace $Namespace -computer $server | where-object { $_.CollectionID -eq $coll }
$coll.AddMembershipRule($CollQuery)
}


#Find ADSites in the current forest
$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() 
$ADSites = $forest.get_Sites()

$ADSites | foreach-object {
#see if the collection already exists
$strFilter = "Name='" + $_ + "'"
if ((gwmi sms_collection -namespace $NameSpace -computername $Server -filter $strfilter| measure).count -eq 1) {
"Collection {0} already exists!" -f $_
}

else {
#Collection doesn't exist, create new collection and rule now
$strWQL = "Select resourceid from SMS_R_System where SMS_R_System.ADSiteName = '$_'"
$Path = "\\" + $Server + "\" + $NameSpace + ":SMS_Collection"
$coll = ([wmiclass] $path).CreateInstance()
$coll.Name = $_.Tostring()
$coll.LimitToCollectionID=$collectionLimiter
#Create refresh schedule - run once a week on Saturdays
$Path = "\\" + $server + "\" + $Namespace + ":SMS_ST_RecurInterval"
$refreshSchedule = ([wmiclass] $path).CreateInstance()
$refreshSchedule.DaySpan = 7
$refreshSchedule.StartTime = "20120804060000.000000+***"
$coll.RefreshSchedule = $refreshSchedule
$coll.RefreshType = 2 #use a value of 6 if you want to enable dynamic collections
#save the collection
$coll.Put()
$coll
#Create the collection Rule
CreateCollectionQueryRule $Coll.CollectionID $Server $Namespace $_.Name.Tostring() $strWQL
}
}

Download CreateCollectionsBasedOnADSites.ps1

Using DateDiff and GetDate in WQL for SMS and ConfigMgr Queries and Collections

Another classic from my old blog (flash back to 2007) – I had to use DateDiff and GetDate in my new ConfigMgr 2012 infrastructure today, so I thought I’d re-post on my new blog…

Queries and collections based on time stamps with DateDiff and GetDate - That’s the best thing that’s happened to collections since. . .well, as long as I can remember. I use these every day, and you should too. A couple years ago, my good friend Warren Byle ran across the following bullet in the SMS 2003 SDK, in a section titled “Extended WMI Query Language”:

  • In SMS 2003 the WHERE clause now supports GetDate(), DateDiff(), and DateAdd().

That’s it. . one small bullet, yet it adds so much functionality to SMS, and makes writing some of my collections much easier, and very low maintenance.

From our book, SMS 2003 Recipes: A Problem-Solution Approach, recipe 9-27 Creating a Date-Based Query:

SMS 2003 supports the following date functions in the WHERE clause of WQL queries.

GetDate(): This function will return the current date and time on the system. The data is returned in date-time format (e.g., 12:56 AM 12/02/2006).

DateDiff(): This function will return the difference between two date-time values in the increment that you specify (e.g., minute, hour, day). In our testing, the DateParts listed in Table 9-1 are supported when using DateDiff in a WHERE clause in SMS WQL.

DateDiff ( DatePart, StartDate, EndDate )

DatePart is the part of the date you want to calculate (e.g., minute, day, month, etc.).

StartDate is the begin date.

EndDate is the ending date.

DateAdd(): Returns a new date-time value based on adding an interval to the specified date. In our testing, the DateParts listed in Table 9-1 are supported when using DateAdd in a WHERE clause in SMS WQL. The proper syntax for DateAdd follows:

DateAdd ( DatePart, Number, Date )

DatePart is the part of the date you want to calculate (e.g., minute, day, month, etc.).

Number is the value to increment DatePart.

Date is a valid date-time value that will be used to calculate the new date.

Note In SMS WQL queries, never put the abbreviation in quotes—this is different than when using DateParts with date functions in VBScript.

Also mentioned in this section is GetDate(), which simply returns the current date-time from the server.

And now for some examples:

All systems that have reported a LastHardwareScan date within the last 30 days:

select *  from  SMS_R_System inner join SMS_G_System_SYSTEM on SMS_G_System_SYSTEM.ResourceID = SMS_R_System.ResourceId inner join SMS_G_System_WORKSTATION_STATUS on SMS_G_System_WORKSTATION_STATUS.ResourceId = SMS_R_System.ResourceId where DATEDIFF(dd,SMS_G_System_WORKSTATION_STATUS.LastHardwareScan,GetDate()) < 30

All systems that have been discovered since midnight:

SELECT SMS_R_System.ResourceID,SMS_R_System.ResourceType,SMS_R_System.Name,  SMS_R_System.SMSUniqueIdentifier,  SMS_R_System.ResourceDomainORWorkgroup,SMS_R_System.Client FROM SMS_R_System WHERE (DateDiff(day, CreationDate, GetDate()) < 1)

Combine these queries with the power of setting the query update interval (by default is 24 hours), and you have a very dynamic query to help you with troubleshooting.  You could also combine my previous blog post on How to Create a Collection Based on Advertisement Status, using DateDiff and the LastStatusTime property from the SMS_ClientAdvertisementStatus class.

Converting to/from WMI Date Time

You will find many posts for how to convert a wmi date-time string to a human-friendly date time here’s one example from Don Jones.

First, here’s an example of the wmi date-time string:

Get-WmiObject -class Win32_OperatingSystem  | select __Server, LastBootUpTime

The value for LastBootUpTime will look something like this: 20120718141700.473048-300. This output is very handy for alpha-sort, by the way…
And Here’s Don’s code:

Get-WmiObject -class Win32_OperatingSystem | Select-Object __SERVER,@{label='LastRestart';expression={$_.ConvertToDateTime($_.LastBootUpTime)}}

Notice how Don elegantly converts the string on the fly with the label and expression arguments.

Now here’s an example of using a COM object to convert the current date time to a wmi date-time string.

$wmidate = new-object -com Wbemscripting.swbemdatetime
$date = get-date -format g
$wmidate.SetVarDate($date,$true)
$wmidate.value

Not nearly as elegant, but it gets the job done. When you create objects in ConfigMgr that require a date-time field, you will usually enter a wmi date-time string.

 

Happy Scripting!

 

Greg

 

Follow

Get every new post delivered to your Inbox.

Join 1,044 other followers