# encoding: ascii
# api: powershell
# title: Get-SCCMUserComputer
# description: In the ConfigMgr environment while performing Application Deployments. Sometimes Users don’t mention their machine names.
# version: 3.0
# type: function
# author: DexterPOSH
# license: CC0
# function: Get-SCCMUserComputer
# x-poshcode-id: 5174
# x-archived: 2014-05-24T12:12:12
# x-published: 2014-05-20T22:49:00
#
# This Function takes either SAMACCOUNTNAME or a Name (uses ADSI to prompt for the matched users) and then retrieves the NetbiosName stored in the instance of the SMS_R_System Class.
# Added the Help
#
function Get-SCCMUserComputer
{
<#
.SYNOPSIS
Gets the NetbiosName for a User (name or SamAccountName)
.DESCRIPTION
Retrieves the NetbiosName property on the SMS_R_System class based on the LastlogonUsername as filter.
Can use the SamAccountNames or a Name to get the machine name, uses ADSI To find the Users when Name is specified.
.EXAMPLE
Get-SCCMUserComputer -identity dexter,Administrator
SamAccountName ComputerName
-------------- ------------
dexter Dexter-PC
Administrator DexterDC
Multiple SamAccountNames can be passed as an input.
By default assumes the localmachine has SMS Provider installed.
.EXAMPLE
Get-SCCMUserComputer -Name "Dexter POSH" -SCCMServer DexSCCM
Name SamAccountName ComputerName
---- -------------- ------------
{Dexter POSH} {dexter} Dexter-PC
When using the Name parameter we can specify the name like below and the space is replaced with a wild card.
ADSI filter used to search for below is 'Dexter*POSH'. Out-Gridview will prompt you to select a User you want
the machine name for. Specify the remote SCCM Server with SMS namespace installed.
.EXAMPLE
This one works the same way but the filter used is "*Dexter*" and this makes the search very slow.
PS C:\> Get-SCCMUserComputer -Name "Dexter" -SCCMServer DexSCCM
Name SamAccountName ComputerName
---- -------------- ------------
{Dexter POSH} {dexter} Dexter-PC
.EXAMPLE
'dexter','Administrator' | Get-SCCMUserComputer -SCCMServer DexSCCM
SamAccountName ComputerName
-------------- ------------
dexter Dexter-PC
Administrator DexterDC
One can pipe the SamAccountNames to the Function as well
.INPUTS
System.String[]
.OUTPUTS
PSObject[]
.NOTES
Written by - DexterPOSH
Blog Url - http://dexterposh.blogspot.com
#>
[CmdletBinding(DefaultParameterSetName="Identity")]
[OutputType([PSObject])]
Param
(
# Specify the SamAccountName for the User
[Parameter(Mandatory=$true,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
ParameterSetName="Identity")]
[string[]]$identity,
# Specify the Name ...ADSI will be used to find the Users matching the criteria
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName="Name")]
[string]$Name,
#specify the SCCMServer having SMS Namespace provider installed for the site. Default is the local machine.
[Parameter(Mandatory=$false)]
[Alias("SMSProvider")]
[String]$SCCMServer=$env:COMPUTERNAME
)
Begin
{
#region open a CIM session
$CIMSessionParams = @{
ComputerName = $SCCMServer
ErrorAction = 'Stop'
}
try
{
If ((Test-WSMan -ComputerName $SCCMServer -ErrorAction SilentlyContinue).ProductVersion -match 'Stack: 3.0')
{
Write-Verbose -Message "[BEGIN] WSMAN is responsive"
$CimSession = New-CimSession @CIMSessionParams
$CimProtocol = $CimSession.protocol
Write-Verbose -Message "[BEGIN] [$CimProtocol] CIM SESSION - Opened"
}
else
{
Write-Verbose -Message "[PROCESS] Attempting to connect with protocol: DCOM"
$CIMSessionParams.SessionOption = New-CimSessionOption -Protocol Dcom
$CimSession = New-CimSession @CIMSessionParams
$CimProtocol = $CimSession.protocol
Write-Verbose -Message "[BEGIN] [$CimProtocol] CIM SESSION - Opened"
}
#endregion open a CIM session
$sccmProvider = Get-CimInstance -query "select * from SMS_ProviderLocation where ProviderForLocalSite = true" -Namespace "root\sms" -CimSession $CimSession -ErrorAction Stop
# Split up the namespace path
$Splits = $sccmProvider.NamespacePath -split "\\", 4
Write-Verbose "[BEGIN] Provider is located on $($sccmProvider.Machine) in namespace $($splits[3])"
# Create a new hash to be passed on later
$hash= @{"CimSession"=$CimSession;"NameSpace"=$Splits[3];"ErrorAction"="Stop"}
}
catch
{
Write-Warning "[BEGIN] $SCCMServer needs to have SMS Namespace Installed"
throw $Error[0].Exception
}
}
Process
{
Switch -exact ($PSCmdlet.ParameterSetName)
{
"Identity"
{
foreach ($id in $identity)
{
$query = "Select NetbiosName from {0} where LastlogonUserName='{1}'" -f "SMS_R_System",$id
Get-CimInstance -Query $query @hash -PipelineVariable UserComputer |
foreach -Process {
[pscustomobject]@{
SamAccountName = $id
ComputerName = $userComputer.netbiosname
}}
}
}
"Name"
{
$adsisearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
if ($Name -notmatch '\s+')
{
$Name = "*$Name*" #Add wildcard * (asterix) if a single name is specified..will be a bit slow after this (ADSI search)
}
$adsisearcher.Filter ='(&(objectCategory=person)(objectClass=user)(name={0}))' -f $($($name -replace '\s+',' ') -replace ' ','*')
$users = $adsisearcher.FindAll()
if ($users.count -ne 0)
{
if ($users.Count -ne 1)
{
$users = $users | select -ExpandProperty properties |
foreach { [pscustomobject]@{Name=$_.name;SamAccountName=$_.samaccountname;Email=$_.mail;Title=$_.title;Location=$_.l} } |
Out-GridView -OutputMode Single -Title "Select the User"
}
$query = "Select NetbiosName from {0} where LastlogonUserName='{1}'" -f "SMS_R_System",$($users.samaccountname)
Get-CimInstance -Query $query @hash -PipelineVariable UserComputer |
foreach -Process {
[pscustomobject]@{
Name=$users.name
SamAccountName = $users.samaccountname
ComputerName = $userComputer.netbiosname
}}
}
else
{
Write-Warning -Message "No Users could be found"
}
}
}
}
End
{
Write-Verbose -Message "[END] Ending the Function"
}
}