I have a PowerShell script to remove an AlwaysOn VPN device tunnel connection from the PCs in my organization. The script executes and removes the connection as expected when I run it locally against the local connection. The problem is that I need to be able to deploy this to remote users and when I've tried it doesn't execute. I have tried to run the script through SCCM and also through a remote PowerShell command line. When I run the script through remote PowerShell session on our SCCM server (WinSvr 2012 R2), I get the following error:
PS C:\Windows\system32> Invoke-Command -FilePath D:\Sources\OS\Settings\Remove-AOVPNConnection-Test2.ps1 -ComputerName WIN10-IT-01
Cannot bind argument to parameter 'InputObject' because it is null.
+ CategoryInfo : InvalidData: (:) [Remove-CimInstance], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.Management.Infrastructure.CimCmdlets.Re
moveCimInstanceCommand
+ PSComputerName : WIN10-IT-01
When I run the script as a package through Microsoft Endpoint Configuration Manager v2006, it reports that the script ran successfully but the connection is not removed from the remote PC and I see the following information in the Ccm32BitLauncher log:
Commandline: "C:\WINDOWS\sysnative\windowsPowershell\v1.0\powershell.exe" -ExecutionPolicy Bypass -File .\Remove-AOVPNConnection-Test.ps1
Working directory: C:\WINDOWS\ccmcache\jh\
Interactive: 0
Window mode: 5
My preferred way to deploy this is through SCCM and originally I assumed that the issue was related to my client being Win10 64-bit and the SCCM client running the 32-bit version of PowerShell despite using the 'sysnative' path (although, I've also tried system32 and syswow64). However, the SCCM server that I ran the remote PS session from, is 64-bit and I still am getting the above error.
Below is the script. It is basically paired Any advice for running this remotely would be greatly appreciated.
[CmdletBinding(SupportsShouldProcess)]
$ProfileName="AlwaysOn VPN"
# // Escape spaces in profile name
$ProfileNameEscaped = $ProfileName -Replace ' ', '%20'
# // Get VPN profile
$CimInstance = Get-CimInstance -Namespace 'root\cimv2\mdm\dmmap' -ClassName 'MDM_VPNv2_01' -Filter "ParentID='./Vendor/MSFT/VPNv2' and InstanceID='$ProfileNameEscaped'"
# // Remove VPN profile
Write-Verbose "Removing VPN connection ""$ProfileName""..."
Remove-CimInstance -CimInstance $CimInstance
// Registry clean-up
Write-Verbose "Cleaning up registry artifacts for VPN connection ""$ProfileName""..."
// Remove registry artifacts from ERM\Tracked
Write-Verbose "Searching for profile $ProfileNameEscaped..."
$BasePath = "HKLM:\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked"
$Tracked = Get-ChildItem -Path $BasePath
ForEach ($Item in $Tracked) {
Write-Verbose "Processing $(Convert-Path $Item.PsPath)..."
$Key = Get-ChildItem $Item.PsPath -Recurse | Where-Object { $_ | Get-ItemProperty -Include "Path*" }
$PathCount = ($Key.Property -Match "Path\d+").Count
Write-Verbose "Found a total of $PathCount Path* entries."
# // There may be more than 1 matching key
ForEach ($K in $Key) {
$Path = $K.Property | Where-Object { $_ -Match "Path\d+" }
$Count = $Path.Count
Write-Verbose "Found $Count Path* entries under $($K.Name)."
ForEach ($P in $Path) {
Write-Verbose "Testing $P..."
$Value = $K.GetValue($P)
If ($Value -Match "$($ProfileNameEscaped)$") {
Write-Verbose "Removing $Value under $($K.Name)..."
$K | Remove-ItemProperty -Name $P
# // Decrement count
$Count--
}
} # // ForEach $P in $Path
# // Update count
Write-Verbose "Setting count to $Count..."
$K | Set-ItemProperty -Name Count -Value $Count
} # // ForEach $K in $Key
} # // ForEach $Item in $Tracked
// Remove registry artifacts from NetworkList\Profiles
$Path = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\'
Write-Verbose "Searching $path for VPN profile ""$ProfileName""..."
$Key = Get-Childitem -Path $Path | Where-Object { (Get-ItemPropertyValue $_.PsPath -Name Description) -eq $ProfileName }
If ($Key) {
Write-Verbose "Removing $($Key.Name)..."
$Key | Remove-Item
}
Else {
Write-Verbose "No profiles found matching ""$ProfileName"" in the network list."
}
// Remove registry artifacts from RasMan\Config
$Path = 'HKLM:\System\CurrentControlSet\Services\RasMan\Config\'
$Name = 'AutoTriggerDisabledProfilesList'
Write-Verbose "Searching $Name under $Path for VPN profile called ""$ProfileName""..."
Try {
# // Get the current registry values as an array of strings
[string[]]$Current = Get-ItemPropertyValue -Path $Path -Name $Name -ErrorAction Stop
}
Catch {
Write-Verbose "$Name does not exist under $Path. No action required."
}
If ($Current) {
#// Create ordered hashtable
$List = [Ordered]@{}
$Current | ForEach-Object { $List.Add("$($_.ToLower())", $_) }
# //Search hashtable for matching VPN profile and remove if present
If ($List.Contains($ProfileName)) {
Write-Verbose "Profile found. Removing entry..."
$List.Remove($ProfileName)
Write-Verbose "Updating the registry..."
Set-ItemProperty -Path $Path -Name $Name -Value $List.Values
}
}
Else {
Write-Verbose "No profiles found matching ""$ProfileName""."
}