Loading
Your Intune Compliance Is Moving to Azure Attestation… and Your Firewall Might Break it
Microsoft is Unifying the Copilot Apps… What IT Admins need to know before September 2026
Remove Device Everywhere – Because Microsoft Thought 3 Portals Was a Good Idea
I Asked Copilot To Make ASCII Art… and It Broke My Soul
AZ-140 Renewal 2025 – What Microsoft Really Tested (and what they didn’t)
I hope you’re having a fantastic week, just as I am. I’ve been scoring big time with all the challenges that have been laid out for me.

I’ll tell you. You might remember my last post, “Optimizing SCCM Deployments: Remove device from collection after OSD” where I faced a significant challenge in removing a device from a device collection after OSD.
Well, that was just the beginning of my adventure with SCCM.

Most devices that are deployed are already registered in SCCM/MECM/MEM and are also domain-joined. This presents some issues:
Besides this, there are administrative issues:
So, I can’t proceed with my work until I find a way to automate this process.

Here’s the plan. I need a PowerShell script that will:
This process needs to be logged, and all errors must be displayed. There’s also the bonus of incorporating a real GUI.
*Side note: The TXT file needs to contain the computer names with MAC address. Something that looks like this:
COMP001,00:00:00:00:00:01
COMP002,00:00:00:00:00:02
etc
This is what the GUI eventually looks like.

Here is this script.
##########
#
# Version 2.3
# - Welcome text when starting
# - Added a cancel button
#
# Version 2.2
# - Pop-up that shows which computers are going to be added
#
# Version 2.1
# - Turned on for troubleshooting. Location: \\SCCMSRV01\software\OSD\Scripts\RemoveDeviceCollection\log\import
#
# Version 2.0
# - Created a GUI
#
# Version 1.5
# - Script check if MAC address is already registered with another machine
#
# Version 1.4.2
# - Added some lines to make the output more clearer
#
# Version 1.4.1
# - Message at the end
#
# Version 1.4
# - Added new variable $addToSCMM. If this is on $false it will not add the computer to SCCM.
#
# Version 1.3
# - If machine has a differet MAC address it will log this in a notepad
# - Added new variable $removeFromAD. If this is set to $false it will not remove from AD
#
# Version 1.2
# - Added a button "Browse" to open a TXT file
# - Each letter will be be uppercased
#
# Version 1.1
# - Machine that already exists in SCCM and MAC address is the same; machine will be removed.
# - Script goes back to local so that it doesn't get stuck at the SCCM server.
#
# Version 1.0
# - Machine that exist will be placed in de deployment collection.
# - Machine that exists and MAC address is correct will be added in de the deployment collection.
# - Machine that does not exists will be added to SCCM and placed in the deployment collection.
# - Machine that exists but has a different MAC address will be notified.
# - Machine will check if it's domain joined and if needed it will be removed from AD.
#
##########
# Versioning
$versionNumber = "v2.3"
# Adding some libraries so that the GUI can work
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Variable for the collections
$allCollectionName = "All Systems"
$deploymentCollectionName = "Windows 10 x64 Deployment" # Still working on getting this automated
# Variabele for logging
$userName = $env:USERNAME
$date = Get-Date
# Location for logging
$logFile = "\\SCCMSRV01\software\OSD\Scripts\RemoveDeviceCollection\log\import\importComputers_$versionNumber.txt"
$logBackup = "\\SCCMSRV01\software\OSD\Scripts\RemoveDeviceCollection\log\import\importComputers_$versionNumber.bak"
# This part will check if the log size isn't too big
if (Test-Path -Path $logFile) {
$logFileSize = (Get-Item -Path $logFile).Length
# Check if log is bigger than 1 MB
if ($logFileSize -gt 1MB) {
# Check if a .bak already exists, if so that delete it first.
if (Test-Path -Path $logBackup) {
Remove-Item -Path $logBackup -Force
}
# Rename current log file extension to .bak
Rename-Item -Path $logFile -NewName $logBackup
}
}
# Here I define the main screen of the GUI including the title and the version number with the variable $versionNumber
$form = New-Object System.Windows.Forms.Form
$form.Text = "SCCM Computer Importer $versionNumber"
$form.Size = New-Object System.Drawing.Size(600,400)
$form.StartPosition = 'CenterScreen'
# Here I define the Browse button
$browseButton = New-Object System.Windows.Forms.Button
$browseButton.Location = New-Object System.Drawing.Point(10,10)
$browseButton.Size = New-Object System.Drawing.Size(100,23)
$browseButton.Text = 'Browse'
$browseButton.Add_Click({
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
$openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
$global:txtFilePath = $openFileDialog.FileName
$startButton.Enabled = $true
}
})
# I have to add the Browse button to the GUI
$form.Controls.Add($browseButton)
# Start button
$startButton = New-Object System.Windows.Forms.Button
$startButton.Location = New-Object System.Drawing.Size(120,10)
$startButton.Size = New-Object System.Drawing.Size(100,23)
$startButton.Text = 'Start'
$startButton.Enabled = $false
$startButton.Add_Click({
$outputTextBox.Clear()
$outputTextBox.AppendText("Script started using file`r`n$global:txtFilePath`r`n`r`n")
# Need to check if a file is selected.
if ($global:txtFilePath -ne $null -and $global:txtFilePath -ne '') {
try{
# Every letter needs to be uppercase. The magic is done here
$fileContent = Get-Content -Path $global:txtFilePath
$computers = $fileContent | ForEach-Object {
# UPPERCASE!!!
$_.ToUpper()
$outputTextBox.AppendText("$upperCaseLine`r`n")
}
} catch {
# Error if the TXT file is corrupted.
$outputTextBox.AppendText("Error reading file: $_`r`n")
}
} else {
$outputTextBox.AppendText("No file selected.`r`n")
}
# I need it to confirm the computers that will be added. I also added a cancel button.
$confirmationMessage = "The following machines will be improted:`r`n`r`n$(($computers -join "`r`n"))`r`n`r`nClick OK to continue or CANCEL to go back."
$confirmationResult = [System.Windows.Forms.MessageBox]::Show($confirmationMessage, "Confirm", [System.Windows.Forms.MessageBoxButtons]::OKCancel, [System.Windows.Forms.MessageBoxIcon]::Information)
# Check what the user does
if ($confirmationResult -ne [System.Windows.Forms.DialogResult]::OK) {
# If user cancels report that
$outputTextBox.AppendText("Cancelled by user`r`n")
return
}
# Let's log before we begin!
"==========`r`n$userName started the script at $date.`r`n`r`n$(($computers -join "`r`n"))`r`n==========" | Add-Content -Path $logFile
# Import the SCCM-Module
try {
Import-Module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)
$outputTextBox.AppendText("SCCM-Module imported.`r`n")
# Change to the SCCM path
Set-Location ((Get-PSDrive -PSProvider CMSite).Name + ":")
$outputTextBox.AppendText("Changed to SCCM path.`r`n")
} catch {
$outputTextBox.AppendText("Error importing SCCM-Module: $_`r`n")
}
# Get information from the deployment collection
$deploymentCollection = Get-CMDeviceCollection -Name $deploymentCollectionName
foreach($computer in $computers){
# Seperate the machine from MAC Address
$details = $computer.Split(',')
$name = $details[0].Trim()
$macAddress = $details[1].Trim()
# Check if machine already exists in SCCM
$sccmComputer = Get-CMDevice -Name $name
$sccmComputerMac = Get-CMDevice | Where-Object { $_.MACAddress -contains $macAddress }
# Variables for continueing with the script
$continueScript = $true
$addToSCCM = $true
$removeFromAD = $true
# Log location for the user
$tempPath = [System.Environment]::ExpandEnvironmentVariables("%TEMP%\importComputer.txt")
$outputTextBox.AppendText("===========================================================================`r`n")
$outputTextBox.AppendText("- Computer $name with MAC $macAddress -`r`n")
# Check if MAC already exists
if ($sccmComputerMac) {
# If the machine name and MAC address are not the same
if ($sccmComputerMac.Name -ne $name) {
$sccmComputerMacName = $sccmComputerMac.Name
$outputTextBox.AppendText("Mac: $macAddress is already registered with $sccmComputerMacName`r`n")
# Save Log
$tempMessage = "- Mac: $macAddress is already registered with computer $sccmComputerMacName. Please check."
Add-Content -Path $tempPath -Value $tempMessage
# Flag to not conintue with this machine
$continueScript = $false
$outputTextBox.AppendText("===========================================================================`r`n")
}
}
# Check if we can continue with the script
if ($continueScript) {
# Check if machine already exists in SCCM
if ($sccmComputer) {
$sccmMacAddress = $sccmComputer.MACAddress
# Machine exists, check MAC address
if ($sccmMacAddress -eq $macAddress) {
$outputTextBox.AppendText("Machine $name with MAC-address $macAddress exists in SCCM`r`n")
# Remove machine en add to the deployment collection
if ($deploymentCollection) {
Remove-CMDevice -DeviceName $name -Force
$outputTextBox.AppendText("Machine $name removed from SCCM.`r`n")
}
} else {
# MAC address is not the same
$outputTextBox.AppendText("Machine $name exists in SCCM, but MAC-address $macAddress is not the same.`r`n")
# Save Log
$tempMessage = "- $name exists in SCCM but MAC-Address $macAddress is not the same. Please check."
Add-Content -Path $tempPath -Value $tempMessage
# Variable for not removing from AD
$removeFromAD = $false
# Variable for not adding to SCCM
$addToSCCM = $false
}
}
# Check if we can add the machine to SCCM
if ($addToSCCM) {
# Machine will be added to SCCM and placed in the deployment collection
Import-CMComputerInformation -CollectionName $allCollectionName,$deploymentCollectionName -ComputerName $name -MacAddress $macAddress
$outputTextBox.AppendText("Machine $name added to SCCM and placed in the deployment collection.`r`n")
}
# Check if machine can be removed from AD
if ($removeFromAD) {
# Check if machine already exists in AD
if (Get-ADComputer -Filter { Name -eq $name }) {
# Remove the AD object
Remove-ADComputer -Identity $name -Confirm:$false
$outputTextBox.AppendText("Machine $name removed from AD.`r`n")
}
}
$outputTextBox.AppendText("===========================================================================`r`n")
}
}
# Update all collections
Invoke-CMCollectionUpdate -Name $allCollectionName
Invoke-CMCollectionUpdate -Name $deploymentCollectionName
# Party
$outputTextBox.AppendText("#############################################`r`n")
$outputTextBox.AppendText("# You are done! #`r`n")
$outputTextBox.AppendText("# Wait 3 minutes before you start #`r`n")
$outputTextBox.AppendText("# Time to PARTY!!! #`r`n")
$outputTextBox.AppendText("#############################################`r`n")
# Check if log file already exist
if (Test-Path -Path $tempPath) {
# Open log file
Invoke-Item -Path $tempPath
# Wait 2 seconds before the temporary log file gets deleted
Start-Sleep -Seconds 2
# Delete the log file
Remove-Item -Path $tempPath -Force
}
})
# Wow... all that and NOW we can add the start button? Damn...
$form.Controls.Add($startButton)
# Output screen
$outputTextBox = New-Object System.Windows.Forms.TextBox
$outputTextBox.Location = New-Object System.Drawing.Point(10,40)
$outputTextBox.Size = New-Object System.Drawing.Size(560,300)
$outputTextBox.Multiline = $true
$outputTextBox.ScrollBars = 'Vertical'
$outputTextBox.Font = New-Object System.Drawing.Font("Consolas", 10)
# Add some explanation in the output field
$introText = "Welcome to the SCCM importer version $versionNumber`r`n" +
"`r`nYou can use a TXT file to add the computers. The TXT file with all computers must look like this:`r`n" +
"`r`n`r`nCOM00001,00:00:00:00:00:01`r`nCOM00002,00:00:00:00:00:02`r`nCOM00003,00:00:00:00:00:03`r`netc.`r`n"
$outputTextBox.Text = $introText
$form.Controls.Add($outputTextBox)
# And here we show the GUI
$form.ShowDialog() | Out-Null
CD C:Automation for the win! There are still a few tasks I need to complete, but the primary goal is to automate the deployment collection process.
Thank you for reading.
Cheers,
Engin Soysal
Engin SoysalMicrosoft MVP and Microsoft Certified Trainer, sharing practical experience with Azure, Microsoft Intune and endpoint engineering.
43 stories · read them all
0 Comments