ConnectWise Extra Data Fields | Setup
Table of Contents
INTRO
We migrated from Datto RMM to ConnectWise Automate | ScreenConnect and it has been a year or so now, so I would like to share the Extra Data Fields that I implemented. I will say ConnectWise Automate requires far more learning and training than Datto RMM, but has many more options and capabilities that are very nice. I would say for those that don’t have the desire or will to dive deep into a platform than you should stay with Datto RMM or other, over ConnectWise. However if you have the drive to dive deep, ConnectWise will be interesting for you and adds some job security since someone won’t be able to just pick it up, it takes weeks of training to understand a good portion of the platform.
SETUP
Below is an example of what I can see when I go to Info -> Extra Data Fields of a computer’s dashboard. Each one links to a custom script I created that when completed sends the output into one of these Extra Data Fields. You will find my PowerShell scripts below except for the Dell Docking Station and Group Policy Base ones as those are still being tested by me still.
Getting started you’re going to first need to create the Extra Data Field headers in the thick-client that will be visible when going to a computer’s dashboard and selecting Info -> Extra Data Fields. I use the thin-client 95% of the time, but I need to use the thick-client from time to time to configure items and use additional features like the RDP tunnel to a device which is not usable in the thin-client.
You install the thick-client by logging into the thin-client and going to System -> Installers -> Automate Control Center where you will be given a Windows-based installer. Once in the thick-client, you need go to System -> Configuration -> Dashboard, then in there you need to navigate to Config -> Configurations -> Additional Fields. Below you will see a picture of my ± Administrator Password field. The special characters used in the name are for sorting in a specific order as I wanted some fields first before others. You can configure the fields and related settings here. Your scripts will have to be configure to output to these fields. I run them on a schedule hourly to run every 8 hours.
EXTRA DATA FIELDS | SCRIPTS
± Administrator Password:
This script will randomize a 10-character password that will consist of Upper-case, Lower-case, Numerals, and Symbols and apply it to the domain or local user account in Windows named Administrator.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @PasswordRotationAdministrator@
# $Error[1].Exception.GetType().FullName
$DomainControllerCheck = (Get-WmiObject -Query "select * from Win32_OperatingSystem where ProductType='2'")
$VerbosePreference = 'Continue'
$Username = "Administrator"
$ErrorActionPreference = 'Stop'
Function Create-String([Int]$Size = 10, [Char[]]$CharSets = "ULNS", [Char[]]$Exclude) {
$Chars = @(); $TokenSet = @()
If (!$TokenSets) {$Global:TokenSets = @{
U = [Char[]]'ABCDEFGHJKMNOPQRSTUVWXYZ' #Upper case
L = [Char[]]'abcdefghjkmnopqrstuvwxyz' #Lower case
N = [Char[]]'0123456789' #Numerals
S = [Char[]]'!#$%&*+=?@' #Symbols
}}
$CharSets | ForEach {
$Tokens = $TokenSets."$_" | ForEach {If ($Exclude -cNotContains $_) {$_}}
If ($Tokens) {
$TokensSet += $Tokens
If ($_ -cle [Char]"Z") {$Chars += $Tokens | Get-Random} #Character sets defined in upper case are mandatory
}
}
While ($Chars.Count -lt $Size) {$Chars += $TokensSet | Get-Random}
($Chars | Sort-Object {Get-Random}) -Join "" #Mix the (mandatory) characters and output string
}
# Generating a new random password.
$Passwd = Create-String 10 UNLS
# Converting random generated password to a secure string for insertion.
$PasswdSecStr = ConvertTo-SecureString $Passwd -AsPlainText -Force
if ($DomainControllerCheck -eq $null ) {
# Write-Verbose "Endpoint is not a Domain Controller, swithcing to local user commands."
try {
# Write-Verbose "Searching for the local user account named $Username in the LocalUser database."
$ObjLocalUser = Get-LocalUser $Username
# Write-Verbose "The local user account named $Username was found."
# Write-Verbose "Setting the new randomly generated password."
Set-LocalUser -Name $Username -Password $PasswdSecStr -PasswordNeverExpires 1
# Write-Verbose "This is the newly random generated password for the local user account named: $Username.";
$Passwd
}
catch [Microsoft.PowerShell.Commands.UserNotFoundException] {
New-LocalUser $Username -Password $PasswdSecStr -FullName $Username -PasswordNeverExpires | Out-Null
# Write-Verbose "Adding the $Username account to the Local Administrators Group."
Add-LocalGroupMember -Group Administrators -Member $Username | Out-Null
# Write-Verbose "This is the newly random generated password for the local user account named: $Username.";
$Passwd
}
}
else {
# Write-Verbose "Endpoint is a Domain Controller, running AD commands."
try {
# Write-Verbose "Searching for the domain user account named $Username in Active Directory."
$ObjADUser = Get-ADUser -Identity $Username
# Write-Verbose "Setting the new randomly generated password."
Set-ADAccountPassword -Identity $Username -Reset -NewPassword $PasswdSecStr
Set-ADUser -Identity $Username -PasswordNeverExpires $True
# Write-Verbose "This is the newly random generated password for the domain user account named: $Username.";
$Passwd
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
# Write-Verbose "Creating a domain user account named $Username and setting the randomly generated password."
New-ADUser -Name $USERNAME -AccountPassword $PasswdSecStr -PasswordNeverExpires $True -Enabled $True
# Write-Verbose "Adding the $Username account to the Administrators Group."
Add-ADGroupMember -Identity Administrators -Members $Username
# Write-Verbose "This is the newly random generated password for the domain user account named: $Username.";
$Passwd
}
}
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: ± Administrator Password
- ID *: %ComputerID%
- Value *: @PasswordRotationAdministrator@
± Support Password:
This script will randomize a 16-character password that will consist of Upper-case, Lower-case, Numerals, and Symbols and apply it the domain or local user account in Windows named Support.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @PasswordRotationSupport@
# $Error[1].Exception.GetType().FullName
$DomainControllerCheck = (Get-WmiObject -Query "select * from Win32_OperatingSystem where ProductType='2'")
$VerbosePreference = 'Continue'
$Username = "Support"
$ErrorActionPreference = 'Stop'
Function Create-String([Int]$Size = 16, [Char[]]$CharSets = "ULNS", [Char[]]$Exclude) {
$Chars = @(); $TokenSet = @()
If (!$TokenSets) {$Global:TokenSets = @{
U = [Char[]]'ABCDEFGHJKMNOPQRSTUVWXYZ' #Upper case
L = [Char[]]'abcdefghjkmnopqrstuvwxyz' #Lower case
N = [Char[]]'0123456789' #Numerals
S = [Char[]]'!#$%&*+=?@' #Symbols
}}
$CharSets | ForEach {
$Tokens = $TokenSets."$_" | ForEach {If ($Exclude -cNotContains $_) {$_}}
If ($Tokens) {
$TokensSet += $Tokens
If ($_ -cle [Char]"Z") {$Chars += $Tokens | Get-Random} #Character sets defined in upper case are mandatory
}
}
While ($Chars.Count -lt $Size) {$Chars += $TokensSet | Get-Random}
($Chars | Sort-Object {Get-Random}) -Join "" #Mix the (mandatory) characters and output string
}
# Generating a new random password.
$Passwd = Create-String 16 UNLS
# Converting random generated password to a secure string for insertion.
$PasswdSecStr = ConvertTo-SecureString $Passwd -AsPlainText -Force
if ($DomainControllerCheck -eq $null ) {
# Write-Verbose "Endpoint is not a Domain Controller, swithcing to local user commands."
try {
# Write-Verbose "Searching for the local user account named $Username in the LocalUser database."
$ObjLocalUser = Get-LocalUser $Username
# Write-Verbose "The local user account named $Username was found."
# Write-Verbose "Setting the new randomly generated password."
Set-LocalUser -Name $Username -Password $PasswdSecStr -PasswordNeverExpires 1
# Write-Verbose "This is the newly random generated password for the local user account named: $Username.";
$Passwd
}
catch [Microsoft.PowerShell.Commands.UserNotFoundException] {
New-LocalUser $Username -Password $PasswdSecStr -FullName $Username -PasswordNeverExpires | Out-Null
# Write-Verbose "Adding the $Username account to the Local Administrators Group."
Add-LocalGroupMember -Group Administrators -Member $Username | Out-Null
# Write-Verbose "This is the newly random generated password for the local user account named: $Username.";
$Passwd
}
}
else {
# Write-Verbose "Endpoint is a Domain Controller, running AD commands."
try {
# Write-Verbose "Searching for the domain user account named $Username in Active Directory."
$ObjADUser = Get-ADUser -Identity $Username
# Write-Verbose "Setting the new randomly generated password."
Set-ADAccountPassword -Identity $Username -Reset -NewPassword $PasswdSecStr
Set-ADUser -Identity $Username -PasswordNeverExpires $True
# Write-Verbose "This is the newly random generated password for the domain user account named: $Username.";
$Passwd
}
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: ± Support Password
- ID *: %ComputerID%
- Value *: @PasswordRotationSupport@
‡ Enabled Local Users:
This Extra Data Field will query enabled local users in Windows.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @EnabledLocalUsers@
$ErrorActionPreference = 'SilentlyContinue'
(Get-LocalUser | where{$_.Enabled -eq 'True'} | Select-Object Name | Format-Table -HideTableHeaders | Out-String).Trim()
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: ‡ Enabled Local Users
- ID *: %ComputerID%
- Value *: @EnabledLocalUsers@
• Alibi
This Extra Data Field will query the Alibi software installed in Windows.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @Alibi@
$ErrorActionPreference = 'SilentlyContinue'
# Get Alibi Products Installed
$Alibi32Bit = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | where{$_.Publisher -like 'Observint Technologies*'} | Select-Object DisplayName, DisplayVersion | Format-Table -HideTableHeaders
$Alibi64Bit = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | where{$_.Publisher -like 'Observint Technologies*'} | Select-Object DisplayName, DisplayVersion | Format-Table -HideTableHeaders
# Merge Values and Output
$Alibi = ($Alibi32Bit, $Alibi64Bit | Out-String).Trim(); $Alibi
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: • Alibi
- ID *: %ComputerID%
- Value *: @Alibi@
• OS Install Date
This Extra Data Field will query the OS install date of Windows.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @OSInstallDate@
$ErrorActionPreference = 'SilentlyContinue'
(Get-ComputerInfo -Property OsInstallDate | Format-Table -HideTableHeaders | Out-String).Trim()
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: • OS Install Date
- ID *: %ComputerID%
- Value *: @OSInstallDate@
• Solidworks Serials
This Extra Data Field will query the serial numbers for Solidworks for the main and visualize licenses in the Windows registry.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @SolidworksSerialNumbers@
$ErrorActionPreference = 'SilentlyContinue'
# Get Solidworks Serial Numbers
$SolidworksMain = Get-ItemProperty -Path "HKLM:\SOFTWARE\SolidWorks\Licenses\Serial Numbers" -Name "SolidWorks" | Select-Object Solidworks | Format-Table
$SolidworksVisualize = Get-ItemProperty -Path "HKLM:\SOFTWARE\SolidWorks\Licenses\Serial Numbers" -Name "Visualize" | Select-Object Visualize | Format-Table
# Merge Values and Output
$SolidworksSerials = ($SolidworksMain, $SolidworksVisualize | Out-String).Trim(); $SolidworksSerials
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: • Solidworks Serials
- ID *: %ComputerID%
- Value *: @SolidworksSerialNumbers@
± BitLocker Recovery Password
This Extra Data Field will query the BitLocker Recovery Password for the C: drive in Windows.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @BitLockerRecoveryPassword@
$ErrorActionPreference = 'SilentlyContinue'
((Get-BitLockerVolume -MountPoint C).KeyProtector | Select-Object RecoveryPassword | Format-Table -HideTableHeaders | Out-String).Trim()
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: ± BitLocker Recovery Password
- ID *: %ComputerID%
- Value *: @BitLockerRecoveryPassword@
‡ Enabled Local Admins
This Extra Data Field will query enabled local Admin accounts.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @EnabledLocalAdmins@
$ErrorActionPreference = 'SilentlyContinue'
(Get-LocalGroupMember Administrators | where{(Get-LocalUser $_.SID -EA 0).Enabled} | Select-Object Name | Format-Table -HideTableHeaders | Out-String).Trim()
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: ‡ Enabled Local Admins
- ID *: %ComputerID%
- Value *: @EnabledLocalAdmins@
• BIOS Firmware Type
This Extra Data Field will query the status in Windows on what BIOS firmware type the is currently set.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @BIOSFirmwareType@
$ErrorActionPreference = 'SilentlyContinue'
(Get-ComputerInfo -Property BiosFirmwareType | Format-Table -HideTableHeaders | Out-String).Trim()
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: • BIOS Firmware Type
- ID *: %ComputerID%
- Value *: @BIOSFirmwareType@
• Intermedia
This Extra Data Field will query the Intermedia software installed in Windows.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @Intermedia@
$ErrorActionPreference = 'SilentlyContinue'
# Get Intermedia Products Installed
$Intermedia32Bit = Get-ItemProperty HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | where{$_.Publisher -like 'Intermedia*'} | Select-Object DisplayName, DisplayVersion | Format-Table -HideTableHeaders
$Intermedia64Bit = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | where{$_.Publisher -like 'Intermedia*'} | Select-Object DisplayName, DisplayVersion | Format-Table -HideTableHeaders
# Merge Values and Output
$Intermedia = ($Intermeida32Bit, $Intermedia64Bit | Out-String).Trim(); $Intermedia
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: • Intermedia
- ID *: %ComputerID%
- Value *: @Intermedia@
• Secure Boot
This Extra Data Field will query the status in Windows on whether Secure Boot is enabled or not.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @SecureBootStatus@
$ErrorActionPreference = 'SilentlyContinue'
(Confirm-SecureBootUEFI | Out-String).Trim()
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: • Secure Boot
- ID *: %ComputerID%
- Value *: @SecureBootStatus@
• Zyxel
This Extra Data Field will query the Zyxel software installed in Windows.
Function: Execute Script
- Script Type: PowerShell Bypass
- Script Parameters: -f -t 00
- Script Credentials *: Local Agent
- Variable: @Zyxel@
$ErrorActionPreference = 'SilentlyContinue'
# Get Zyxel Products Installed
$Zyxel32Bit = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | where{$_.Publisher -like 'Zyxel*'} | Select-Object DisplayName, DisplayVersion | Format-Table -HideTableHeaders
$Zyxel64Bit = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | where{$_.Publisher -like 'Zyxel*'} | Select-Object DisplayName, DisplayVersion | Format-Table -HideTableHeaders
# Merge Values and Output
$Zyxel = ($Zyxel32Bit, $Zyxel64Bit | Out-String).Trim(); $Zyxel
Function: ExtraData Set Value
- Scope: Computer
- Extra Data Field *: • Zyxel
- ID *: %ComputerID%
- Value *: @Zyxel@
CONCLUSION
Well that’s it, hope this post helped you and guided you on how to better utilize ConnectWise Automate.
My name is Dex Sandel, author at WinReflection, a blog which aims to help others on various IT and Christian related subjects. DON’T TREAD ON ME! The best is yet to come, and nothing can stop what’s coming!
You all have a greater destiny in Christ, should you choose to ‘follow’ Him, not just believe. Many of you feel lost, without drive, and lack a greater purpose in your life causing depression, sadness, anxiety, and loneliness. Working your 9-5 job isn’t your primary purpose. So, then what is? That’s for you to discover, but hopefully I can provide some new unlocks along your path.
What will ‘you’ do, and what will your destiny be?
John 3:16: For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life.
Are you able to update EDF’s that have checkbox types? or is it just text. I have a number of boolean values I want to use the checkbox with ideally. If I just have to save True/False to a text I suppose that is fine but less ideal.
That’s a good question. I do not have an answer as I did not use checkboxes. There may be a function included in CW that can check a box for an EDF. Would be a good question for CW support.