I'm trying to automate via PowerShell a number of time consuming tasks that I have to preform to make a new VM template, one of which is removing all of the NICs from the VM and cleaning up the Device Manager of non present devices.
After removing the NICs from the VM, I've tried using the following code snippets, which do the same thing, to clean up Device Manager.
wmic nic where "(servicename is null)" delete
gwmi win32_networkadapter | ?{$_.ServiceName -eq $null} | rwmi
In both cases I receive the error "Provider is not capable of the attempted operation". Reviewing the event logs for WMI-Activity didn't seem to help: ResultCode = 0x80041024; PossibleCause = Unknown.
Has anyone be able to do something similar that removes the non present devices or is able to find an issue with the above commands?
EDIT: I've tried using DevCon to remove the device, but it seems to only work with present devices. I'm now combing through the registry to see if there is a specific key or set of keys that if removed would remove the NIC from Device Manager.
This registry key contains all of the hardware settings of the machine within the registry:
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum
First query the present and enabled Network Adapters through WMI and get their PNPDeviceId. This value will tell you which subkey the Network Adapters are located in.
Next query the registry for each subkey and find all of the Adapters. Parse the full registry key to cut down to the same length as the PNPDeviceId values; roughly PCI\VEN_80AD&DEV_15A2&SUBSYS_062D1028&REV_02\2&11483669&0&C9.
Compare the two lists and find any orphaned registry keys. Once found, deleting the registry keys by enumerating the system account will remove the Network Adapter from Device Manager. I used PSExec.exe to run the reg delete command as the system account.
Here is some code to perform what I just explained.
# Declare variables
[string]$regIds = "";
[string]$Orphans = "";
[array]$SubKeys = @();
[array]$RegKeys = @();
# Query the present and enabled Network Adapters for the PNPDeviceId value
[array]$PNPDeviceIds = (gwmi Win32_NetworkAdapter -Filter "NetEnabled = true").PNPDeviceId;
for ($i = 0; $i -lt $PNPDeviceIds.Count; $i++){
if ($SubKeys -NotContains $($PNPDeviceIds[$i].Split('\')[0] + "\" + $PNPDeviceIds[$i].Split('\')[1])){
$SubKeys += $($PNPDeviceIds[$i].Split('\')[0] + "\" + $PNPDeviceIds[$i].Split('\')[1]);
}}
# Query the registry for all of the adapters
foreach ($SubKey in $SubKeys){
[array]$Keys = reg query "hklm\system\currentcontrolset\enum\$SubKey"
$Keys = $Keys[1..$($Keys.Count -1)];
$RegKeys += $Keys;
}
# Parse the Keys
for ($i = 0; $i -lt $RegKeys.Count; $i++){ $regIds += "," + $($RegKeys[$i].Split('\')[4..6] -join '\'); }
$regIds = $regIds.TrimStart(",");
# Compare the registry to the present devices
for ($i = 0; $i -lt $regIds.Split(',').Count; $i++){
if ($PNPDeviceIds -NotContains $regIds.Split(',')[$i]){
$Orphans += "," + $regIds.Split(',')[$i];
}}
if ($Orphans.Length -gt 0){ $Orphans = $Orphans.TrimStart(","); }
# Delete the non-present devices
foreach ($Orphan in $Orphans)
{
psexec.exe -s powershell.exe "reg delete 'hklm\system\currentcontrolset\enum\$Orphan'"
}