Tuesday, May 20, 2014

PowerShell + SCCM Tip: Get MachineName for a User

While doing Application deployments , we have cases where the User forgets to specify the Machine Name to which a software needs to be deployed to.

We use Query-Based Deployment rules in ConfigMgr where we add the machine names to a Collection named after the Application..have already automated this process ;)

But if the machine name is not specified then we either:

  1. Get the Machine name from SCCM Reports if available.
  2. Drop an email to the Requester for the same
For getting the machine name for a User in ConfigMgr 07 we use the Reports obviously :D

The report is located under "Users" node in ConfigMgr Reports page.

But actually this can be retrieved using WMI/CIM too.

The Class which has this info is SMS_R_System under namespace Root/SMS/site_<SiteCode> and let's take a look at it.

Note: Before going further I have already set the ComputerName parameter and namespace parameter in the $PSDefaultParameters. Below is how you do it in PS Console.
$PSDefaultParameterValues = @{"Get-WMIObject:Namespace"="Root/SMS/site_DEX";"Get-WMIObject:ComputerName"="DexSCCM";"Get-CIMCLass:Namespace"="Root/SMS/site_DEX";"Get-CImClass:ComputerName"="DexSCCM"}

Now let's look at the properties of the class we are interested in. 

Now let's use the Get-WMIObject or Get-CIMInstance to get a machine name for a user "Administrator"

Note doing this in my Lab so just going ahead with the User "Administrator". This works for both ConfigMgr 07 and 12 that's the beauty of using WMI ;)

Get-CimInstance -Query "Select NetbiosName from SMS_R_System where lastlogonusername='Administrator'"
You will notice that running the above will only return back the netbiosname property...doing this as it is the only information am after right now.

For the above WMI/CIM query we need to know the SamAccountName of the User, so suppose we have a User Named "Dexter POSH" then we could leverage ADSI here to filter out the User's matching the name.

So I have written a Function named Get-SCCMUserComputer which does all this.

After you have loaded the function then you can run it like below to pass samaccountnames to the -Identity parameter
Get-SCCMUserComputer -identity administrator -Verbose
VERBOSE: [BEGIN] WSMAN is responsive
VERBOSE: Operation '' complete.
VERBOSE: Perform operation 'Query CimInstances' with following parameters, ''queryExpression' = select * from SMS_ProviderLocation where ProviderForLocalSite = true,
'queryDialect' = WQL,'namespaceName' = root\sms'.
VERBOSE: Operation 'Query CimInstances' complete.
VERBOSE: [BEGIN] Provider is located on DexSCCM.dexter.com in namespace root\sms\site_DEX
VERBOSE: Perform operation 'Query CimInstances' with following parameters, ''queryExpression' = Select NetbiosName from SMS_R_System where LastlogonUserName='adminis
trator','queryDialect' = WQL,'namespaceName' = root\sms\site_DEX'.

SamAccountName                                                                     ComputerName                                                                     
--------------                                                                     ------------                                                                     
administrator                                                                      DEXTERDC                                                                         
VERBOSE: Operation 'Query CimInstances' complete.
VERBOSE: [END] Ending the Function

Now there is another parameter by the name -Name :P
So what it does is it uses ADSI to search the domain for matching users and prompts you to select one out of those to move forward. Let me show that real quick so if I invoke the function like below:
Get-SCCMUserComputer -Name Admin -Verbose

Now the Script will use "*Admin*" to search the AD using ADSI and ask you to select the Users (multiple Users can be selected... :) )you want to get the netbiosname for..below is a screenshot showing this:

Only other thing worth mentioning is that when using the -Name parameter how the ADSI filter is created.  If you specify a Name without any spaces then an asterix is added to both start and end to filter out using ADSI.
For Ex - In above example "Admin" was specified and the filter used is "*Admin*"

But if I specify an argument "Dexter POSH" then the filter used is "Dexter*POSH" I did this because if someone is specifying the name in this way then he probably knows what is the first and last name he is searching for.

Not saying the best way but am going ahead with this....any inputs are welcomed.

NOTE -- Sometimes this information might not be populated there in SCCM so if this is not available then one needs to drop an email asking the User for the Machinename.

Hope this saves a few Mouse clicks for someone.
This is it for today's post.

Below is the Gist and Technet Script Link: