All documentation

Streamline Remote Machine Access with PowerShell and SCCM Integration

Published July 12, 2023 Guide

Remote machine access is a crucial aspect of IT administration and support. In this tech article, we will explore how to leverage the PowerShell module on Windows to connect to a Windows machine via SCCM (System Center Configuration Manager). By utilizing the provided script, we can easily connect to a user's primary device, choose from a list of primary devices, call the SCCM executable from the command-line interface (CLI), send wake packets to wake up sleeping machines, and log events for future reference. We will also guide you on obtaining the script from a GitHub repository. Let's explore the benefits and procedures.

Benefits of Using PowerShell and SCCM:

  1. Connecting to a User's Primary Device:
    One significant benefit of the PowerShell script is the ability to connect to a user's primary device. This ensures that you are connecting to the correct machine for support or administrative tasks, leading to more efficient troubleshooting and user assistance.
  2. Choosing from a List of Primary Devices:
    In scenarios where a user has multiple primary devices, the script allows you to select from a list of available devices. This flexibility empowers you to connect to the desired device and avoid any confusion or potential mistakes caused by connecting to the wrong machine.
  3. Calling the SCCM Executable from CLI:
    The script seamlessly integrates with SCCM by calling the SCCM executable from the command-line interface. This eliminates the need for manual navigation through the SCCM user interface and enables a quicker and more streamlined connection process.
  4. Sending Wake Packets to Wake Sleeping Machines:
    When a target machine is in sleep mode, establishing a remote connection can be challenging. The PowerShell script includes functionality to send wake packets, which wake up sleeping machines remotely. This capability ensures uninterrupted access, even when the target machine is in a low-power state.
  5. Logging Events for Future Reference:
    The script incorporates event logging, allowing you to keep a record of important events during the remote connection process. Logging events provides a valuable reference for troubleshooting, auditing actions performed on the machines, and analyzing usage patterns.

Step-by-Step Guide:

  1. Obtaining the Script:
    To obtain the PowerShell script, follow these steps:
  1. Adjusting Execution Policy:
    Before running the script, ensure that the PowerShell execution policy allows script execution. Follow these steps:
  • Open a PowerShell console with administrative privileges.
  • Set the execution policy by running the following command:
    powershell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
  1. Navigating to the Script Directory:
    In the PowerShell console, navigate to the directory where the script is saved. For example:
   cd C:\Scripts
  1. Example Usage: Connecting to a User's Primary Device:
    To connect to a user's primary device, execute the following command:
   .\ConnectViaSCCM.ps1 -user "Username" -showPrimaryDeviceOnly

Replace "Username" with the appropriate username. This command retrieves the primary device for the specified user and displays a list of available primary devices to choose from. Select the desired device from the list.

  1. Example Usage: Connecting to a Specific Computer:
    To connect to a specific computer via SCCM, execute the following command:
   .\ConnectViaSCCM.ps1 -computer "ComputerName"

Replace "ComputerName" with the name of the target computer. This command initiates a connection to the specified computer using SCCM.

  1. Example Usage: Sending Wake Packets to a Sleeping Machine:
    To send wake packets and wake up a sleeping machine before establishing a remote connection, use the following command:
   .\ConnectViaSCCM.ps1 -computer "ComputerName" -SendWakePacket

Replace "ComputerName" with the name of the target computer. This command sends wake packets to wake up the sleeping machine and then connects to it using SCCM.

  1. Enjoy Remote Machine Access:
    After executing the script with the desired parameters, you will establish a remote connection to the specified computer via SCCM. This remote access enables you to perform various administrative tasks, troubleshooting, or user support.


Here is the complete PowerShell script for connecting to a Windows machine via SCCM:
By utilizing the PowerShell script and integrating it with SCCM, remote machine access becomes more streamlined and efficient. The script enables you to connect to a user's primary device, choose from a list of primary devices, call the SCCM executable from the CLI, send wake packets to wake up sleeping machines, and log events for future reference. Follow the step-by-step guide and leverage the script's examples to enhance your remote support and administration capabilities. Download the script from the provided GitHub repository, adapt it to your environment, and enjoy a more productive and seamless remote machine access experience.

Complete Script:

## Connect Via SCCM 
## Chris Tejeda
## 7/2018

Function Connect-ViaSCCM {

[CmdletBinding()]
    param 
    (
        [Parameter(Mandatory=$false)]
        [string]$computer,
        [Parameter(Mandatory=$false)]
        [string]$user,
        [Parameter(Mandatory=$false)]
        [switch]$SendWakePacket,
        [Parameter(Mandatory=$false)]
        [switch]$showPrimaryDeviceOnly,
        [Parameter(Mandatory=$false)]
        [switch]$RunSCCMActions,
        [Parameter(Mandatory=$false)]
        [string]$MacUser
          
    )

Function Invoke-Logger {

    [CmdletBinding()]
    param 
    (
        [Parameter(Mandatory=$true)]
        [string]$Message,
        [Parameter(Mandatory=$true)]
        [string]$LogFile,
        [Parameter(Mandatory=$false)]
        [Switch]$ShowOutput,
        [Parameter(Mandatory=$false)]
        [Switch]$SaveToCSV,
        [Parameter(Mandatory=$false)]
        [Switch]$ShowError,
        [Parameter(Mandatory=$false)]
        [Switch]$ShowWarning
    )
        $date = Get-Date -UFormat "%m/%d/%Y %H:%M:%S"
        $Global:logfile = "$env:USERPROFILE\sccm-connect.log"
        Add-Content $LogFile -Value "$date - $Message"
        if ($ShowOutput)
        {$ShowOutput = Write-Host $Message -ForegroundColor Green }
        if ($ShowError)
        {$ShowError = Write-Host $Message -ForegroundColor Red }
        if ($ShowWarning)
        {$ShowWarning = Write-Host $Message -ForegroundColor Yellow }
        if ($SaveToCSV){$array = @(); $array += [pscustomobject] @{"computer" = $computer; "Message" = "$Message"; "Date" = "$date" }; $array | Export-Csv -Path "$env:USERPROFILE\sccm-connect.csv" -NoTypeInformation }
        $ErrorActionPreference='stop'
        
}
$Global:logfile = "c:\Connect-ViaSCCM.log"
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
Function Write-Menu
{
	
	
	[CmdletBinding()]
	[Alias("menu")]
	Param (
		[Parameter(Mandatory, Position = 0)]
		[Alias("MenuEntry", "List")]
		$Menu
		 ,
		[Parameter(Mandatory = $false, Position = 1)]
		[string]$PropertyToShow = 'Name'
		 ,
		[Parameter(Mandatory = $false, Position = 2)]
		[ValidateNotNullorEmpty()]
		[string]$Prompt = 'Pick a choice'
		 ,
		[Parameter(Mandatory = $false, Position = 3)]
		[Alias("Title")]
		[string]$Header = ''
		 ,
		[Parameter(Mandatory = $false, Position = 4)]
		[ValidateRange(0, 5)]
		[Alias("Tab", "MenuShift")]
		[int]$Shift = 0
		 ,
		[Parameter(Mandatory = $false, Position = 5)]
		[Alias("Color", "MenuColor")]
		[System.ConsoleColor]$TextColor = 'White'
		 ,
		[Parameter(Mandatory = $false, Position = 6)]
		[System.ConsoleColor]$HeaderColor = 'Yellow'
		 ,
		[Parameter(Mandatory = $false)]
		[ValidateNotNullorEmpty()]
		[Alias("Exit", "AllowExit")]
		[switch]$AddExit
	)
	
	Begin
	{
		$ErrorActionPreference = 'Stop'
		if ($Menu -isnot [array]) { $Menu = @($Menu) }
		if ($Menu[0] -is [psobject] -and $Menu[0] -isnot [string])
		{
			if (!($Menu | Get-Member -MemberType Property, NoteProperty -Name $PropertyToShow)) { Throw "Property [$PropertyToShow] does not exist" }
		}
		$MaxLength = if ($AddExit) { 8 }
		else { 9 }
		$AddZero = if ($Menu.Length -gt $MaxLength) { $true }
		else { $false }
		[hashtable]$htMenu = @{ }
	}
	Process
	{
		### Write menu header ###
		if ($Header -ne '') { Write-Host $Header -ForegroundColor $HeaderColor }
		
		### Create shift prefix ###
		if ($Shift -gt 0) { $Prefix = [string]"`t" * $Shift }
		
		### Build menu hash table ###
		for ($i = 1; $i -le $Menu.Length; $i++)
		{
			$Key = if ($AddZero)
			{
				$lz = if ($AddExit) { ([string]($Menu.Length + 1)).Length - ([string]$i).Length }
				else { ([string]$Menu.Length).Length - ([string]$i).Length }
				"0" * $lz + "$i"
			}
			else
			{
				"$i"
			}
			
			$htMenu.Add($Key, $Menu[$i - 1])
			
			if ($Menu[$i] -isnot 'string' -and ($Menu[$i - 1].$PropertyToShow))
			{
				Write-Host "$Prefix[$Key] $($Menu[$i - 1].$PropertyToShow)" -ForegroundColor $TextColor
			}
			else
			{
				Write-Host "$Prefix[$Key] $($Menu[$i - 1])" -ForegroundColor $TextColor
			}
		}
		
		### Add 'Exit' row ###
		if ($AddExit)
		{
			[string]$Key = $Menu.Length + 1
			$htMenu.Add($Key, "Exit")
			Write-Host "$Prefix[$Key] Exit" -ForegroundColor $TextColor
		}
		
		### Pick a choice ###
		Do
		{
			$Choice = Read-Host -Prompt $Prompt
			$KeyChoice = if ($AddZero)
			{
				$lz = if ($AddExit) { ([string]($Menu.Length + 1)).Length - $Choice.Length }
				else { ([string]$Menu.Length).Length - $Choice.Length }
				if ($lz -gt 0) { "0" * $lz + "$Choice" }
				else { $Choice }
			}
			else
			{
				$Choice
			}
		}
		Until ($htMenu.ContainsKey($KeyChoice))
	}
	End
	{
		return $htMenu.get_Item($KeyChoice)
	}
	
} 

if ($RunSCCMActions) 

{

Invoke-Logger -Message "Starting the SCCM Actions on $Computer" -Logfile $logfile -Showoutput
Import-Module "\\share\folder\path\SCCM\Start-CMClientAction.ps1"
Start-CMClientAction -ComputerName $computer -SCCMActionsBundle

}

if ($showPrimaryDeviceOnly)
{
try {
$PWD = pwd
Import-Module "\\share\folder\path\PowerShell Portable Modules\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
$SCCMserver = "sccm-server"
$SCCMnameSpace = "root\SMS\LIC"
cd LIC: -ErrorAction SilentlyContinue
$user = $user
$username = "smcorp\\$user"
Invoke-Logger -Message "Retriving primary device for $user" -LogFile $logfile -ShowOutput
$usercomputer = Get-WmiObject -Namespace "root\SMS\Site_lic" -Class SMS_UserMachineRelationship -ComputerName $SCCMserver -Filter "UniqueUserName='$UserName' and ResourceClientType='1'" | ? {$_.isactive -eq "True"} | select -ExpandProperty resourcename
 

if ($usercomputer.count -gt 1) 
{

Invoke-Logger -Message "Multiple Devices Detected as primary device for User: $user" -LogFile $logfile -ShowOutput

$usercomputerArray = @()

$usercomputer.split()  | % { 

$Model = Get-WmiObject Win32_Computersystem -ComputerName $_ | select -ExpandProperty Model -ErrorAction SilentlyContinue
$manu = Get-WmiObject Win32_Computersystem -ComputerName $_ | select -ExpandProperty Manufacturer -ErrorAction SilentlyContinue

$usercomputerArray += [pscustomobject] @{"Name" = "$_"; "Model" = "$Model"; "Manufacturer" = "$manu"}
#$usercomputerArray += [pscustomobject] @{"Device" = "$_"}

 }

$usercomputerArray

cd $PWD

}

else 

{
Invoke-Logger -Message "The follwoing Primary device $usercomputer was found for user: $user" -LogFile $logfile -ShowOutput 
cd $PWD

$Model = Get-WmiObject Win32_Computersystem -ComputerName $usercomputer | select -ExpandProperty Model
$manu = Get-WmiObject Win32_Computersystem -ComputerName $usercomputer | select -ExpandProperty Manufacturer

$usercomputerArray = @()
$usercomputerArray += [pscustomobject] @{"Name" = "$usercomputer";"Model" = "$Model"; "Manufacturer" = "$manu"}
#$usercomputerArray += [pscustomobject] @{"Name" = "$usercomputer"}
$usercomputerArray 

}

}
catch {$_}
}
elseif ($MacUser)
{

Start-Process -FilePath "\\share\folder\path\RealVNC\VNC Viewer\vncviewer.exe" "$MacUser"

}
elseif ($user) 
{

$PWD = pwd
Import-Module "\\share\folder\path\PowerShell Portable Modules\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
$SCCMserver = "sccm-server"
$SCCMnameSpace = "root\SMS\LIC"
cd LIC: -ErrorAction SilentlyContinue
$username = "smcorp\\$user"
Invoke-Logger -Message "Retriving primary device for $user" -LogFile $logfile -ShowOutput
$usercomputer = Get-WmiObject -Namespace "root\SMS\sccm_site" -Class SMS_UserMachineRelationship  -ComputerName $SCCMserver  -Filter "UniqueUserName='$UserName' and ResourceClientType='1'" | ? {$_.isactive -eq "True"} | select -ExpandProperty resourcename

if ($usercomputer.count -gt 1) 
{

Invoke-Logger -Message "Multiple Devices Detected as primary device for User: $user" -LogFile $logfile -ShowOutput

$usercomputerArray = @()

$usercomputer.split()  | % { $usercomputerArray += [pscustomobject] @{"Name" = "$_"} }

$pc = Write-Menu -Menu ($usercomputerArray) -Prompt "Choose a Device to Connect to" -TextColor Cyan 

$pcname = $pc.name

Invoke-Logger -Message "The follwoing Primary device $pcname has been selected for user: $user" -LogFile $logfile -ShowOutput
cd $PWD -ErrorAction SilentlyContinue
Invoke-Logger -Message "Connection to $pcname using SCCM Client" -LogFile $logfile -ShowOutput
Start-Process "\\share\folder\path\CmRcViewer.exe" "$pcname"
}

else 

{

if ($usercomputer)

{
Invoke-Logger -Message "The follwoing Primary device $usercomputer was found for user: $user" -LogFile $logfile -ShowOutput 
cd $PWD -InformationAction Ignore
Start-Process "\\share\folder\path\CmRcViewer.exe" "$usercomputer" 
}

else {Invoke-Logger -Message "No Device Found for user $user" -LogFile $logfile -ShowError}

}

}
elseif (!$SendWakePacket) 
{
Invoke-Logger -Message "Connecting to $computer via SCCM Client" -LogFile $logfile -ShowOutput
Start-Process "\\share\folder\path\CmRcViewer.exe" "$computer"
}
elseif ($computer) 
{

$PWD = pwd
Import-Module "\\share\folder\path\PowerShell Portable Modules\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
$SCCMserver = "sccm-server"
$SCCMnameSpace = "root\SMS\LIC"
cd LIC: -ErrorAction SilentlyContinue
## Optian mac address for computer
$MACAddress = (Get-WmiObject -Class SMS_R_SYSTEM -Namespace "root\sms\scc-site" -computerName $SCCMserver | where {$_.Name -eq "$computer"})  | select -ExpandProperty MACAddresses
## Change directory back to power working directory
cd $PWD -InformationAction Ignore
## Send wake packet to PC
$Mac = $MACAddress
$MacByteArray = $Mac -split "[:-]" | ForEach-Object { [Byte] "0x$_"}
[Byte[]] $MagicPacket = (,0xFF * 6) + ($MacByteArray  * 16)
$UdpClient = New-Object System.Net.Sockets.UdpClient
$UdpClient.Connect(([System.Net.IPAddress]::Broadcast),7)
$UdpClient.Send($MagicPacket,$MagicPacket.Length)
$UdpClient.Close()
sleep -Seconds 3

Start-Process "\\share\folder\path\CmRcViewer.exe" "$computer"}

else 
{ Invoke-Logger -Message "The Following error has occured: $_" -LogFile $logfile -ShowError}

}