Marli-Net.ps1

function Marli-Net {
    Do {
        $ErrorActionPreference = 'SilentlyContinue'
  
        $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
        $testadmin = $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
        if ($testadmin -eq $false) {
            Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
            exit $LASTEXITCODE
        }

        [string]$Global:Sequ1 = ""
        [string]$Global:Sequ2 = ""
        [string]$Global:Sequ3 = ""
        [string]$Global:Sequ4 = ""

        #### - CONVERTER - ##################################################################################################################################
        filter ConvertTo-MaskLength {
            [CmdletBinding()]
            [OutputType([Int32])]
            param (
                [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
                [Alias("Mask")]
                [IPAddress]$SubnetMask
            )
    
            $binaryOctets = $SubnetMask.GetAddressBytes() | ForEach-Object { 
                [Convert]::ToString($_, 2)
            }
    ($binaryOctets -join '').Trim('0').Length
        }

        ######################################################################################################################################################
        function Conv ([int]$Sque_Nr) {
            [string]$Sequence = ""
            Do {
                If (!($Global:Suffix -eq 0)) {
                    $Global:Suffix = $Global:Suffix - 1
                    $Sequence = $Sequence + "1"
                }
                else { $Sequence = $Sequence + "0" }
    
            }While (!($Sequence -match ".{8}"))

            if ($Sque_Nr -eq 1) { $Global:Sequ1 = [convert]::ToInt32($Sequence, 2) }
            elseif ($Sque_Nr -eq 2) { $Global:Sequ2 = [convert]::ToInt32($Sequence, 2) }
            elseif ($Sque_Nr -eq 3) { $Global:Sequ3 = [convert]::ToInt32($Sequence, 2) }
            elseif ($Sque_Nr -eq 4) { $Global:Sequ4 = [convert]::ToInt32($Sequence, 2) }
        }
        function Config () {
            function Convert-ToTable {
                param([Parameter(Position = 0, Mandatory = $true)] [string]$Variable)
    
                $List = @()
                ForEach ($line in $($Variable -split "`r`n")) {
                    $List += $line
                }
                return $List
            }
   
            $GW = Get-NetIPConfiguration -InterfaceAlias $UString.InterfaceAlias | Out-String
            Foreach ($entry in Convert-ToTable $GW ) {
                If ($entry -like 'IPv4DefaultGateway*') {
                    $UIPGWA = $entry.Split(':')[1].Trim()
                    break
                }
            }
   
            $UAdapter = Get-NetAdapter -InterfaceAlias $UString.InterfaceAlias | Select-Object -ExpandProperty InterfaceDescription
            $UIP4vA = Get-NetIPAddress -InterfaceAlias $UString.InterfaceAlias | Select-Object -ExpandProperty IPv4Address
            [string]$DHCP_check = Get-NetIPAddress -InterfaceAlias $UString.InterfaceAlias | Select-Object -ExpandProperty "PrefixOrigin"
            [string]$DHCP_active = $DHCP_check.ToString().ToUpper()
            $UIPdnsA = Get-DnsClientServerAddress -InterfaceAlias $UString.InterfaceAlias | Select-Object -ExpandProperty ServerAddresses
            
            #$UString | Out-File -FilePath 'C:\tmp\error.txt' -Encoding utf8 -Append
            
            [byte]$Global:Suffix = Get-NetIPAddress -InterfaceAlias $UString.InterfaceAlias | Select-Object -ExpandProperty "PrefixLength"

            Conv 1
            Conv 2
            Conv 3
            Conv 4
   
            $SUBMASK = -join ($Global:Sequ1, ".", $Global:Sequ2, ".", $Global:Sequ3, ".", $Global:Sequ4)
            ###########################################################################
            Clear-Host
            Write-Host ""
            Write-Host "Networkcard changer"
            Write-Host "-------------------"
            Write-Host ""
            Write-Host $UAdapter -ForegroundColor yellow
            Write-Host "_______________________________________________________________________________"
            Write-Host ""
            Write-Host "Current configuration:"
            Write-Host "IP-Address:" `t -NoNewline
            Write-Host $UIP4vA  -ForegroundColor Yellow -NoNewline
            Write-Host " (" -NoNewline
            Write-Host $DHCP_active -ForegroundColor Green -NoNewline
            Write-Host ")"
            Write-Host "Subnetmask:" `t -NoNewline
            Write-Host $SUBMASK  -ForegroundColor Yellow
            Write-Host "Gateway:" `t -NoNewline
            Write-Host $UIPGWA -ForegroundColor Yellow -NoNewline
            Write-Host "DNS-Address:" `t -NoNewline
            Write-Host $UIPdnsA  -ForegroundColor Yellow
            Write-Host "_______________________________________________________________________________"
   
            Read-Host
        }
        #########################################################################################################################################################
        #########################################################################################################################################################
        #########################################################################################################################################################
  
        Do {
            $UString = Get-NetIPInterface | Select-Object InterfaceAlias, AddressFamily, ConnectionState
            $maxLines = $UString | measure
            Clear-Host
            Write-Host ""
            Write-Host "Networkcard changer"
            Write-Host "-------------------"
            Write-Host ""
            Write-Host 'Please select affected Network-Adapter'
            Write-Host ""
            Write-Host ""
            Write-Host " Nr. Adapter (Connection Status)"
            Write-Host "__________________________________________________________________________"
            [int]$Numb = 1
            foreach ($UString in $UString) {
                If ($UString.InterfaceAlias -notmatch "Loopback" -and $UString.AddressFamily -eq "IPv4" -and $UString.InterfaceAlias -notmatch "Bluetooth" ) {
                    $UAdapter = Get-NetAdapter $UString.InterfaceAlias | Select-Object -ExpandProperty InterfaceDescription
                    $USpeed = Get-NetAdapter $UString.InterfaceAlias | Select-Object -ExpandProperty Speed
                }
                else { $UAdapter = "" }

                If (!($UAdapter -le ".{1}")) {
                    Write-Host '[ ' -NoNewline
                    Write-Host $Numb -NoNewline -ForegroundColor Yellow
                    Write-Host ' ]>------- ' -NoNewline
                    Write-Host `t -NoNewline
                    Write-Host $UAdapter  -NoNewline
                    Write-Host ' (' -NoNewline -ForegroundColor Yellow
                    Write-Host $([math]::Round($USpeed / 1MB)) -NoNewline -ForegroundColor Yellow
                    Write-Host ' MBit/s)' -NoNewline -ForegroundColor Yellow
                    If ($UString.ConnectionState -eq "Connected") {
                        Write-Host " (Connected)" -ForegroundColor Green
                    }
                    else {
                        Write-Host " (Disconnected)" -ForegroundColor Red
                    }

                    $Numb = $Numb + 1
                }
            }
            $maxLines = $UString | measure
            Write-Host "__________________________________________________________________________"
            [int]$Nr = Read-Host 'Select Nr'
        } While ($Nr -lt 1 -or $Nr -gt $maxLines)

        ###########################################################################

        Clear-Host
        $NrSWList = '[ ' + $Nr + ' ]'
        $UString = Get-NetIPInterface | Select-Object InterfaceAlias, AddressFamily, ConnectionState
        [int]$Numb = 1

        $loopbreaker = "false"
        ###########################################################################
        foreach ($UString in $UString) {
            If ($UString.InterfaceAlias -notmatch "Loopback" -and $UString.AddressFamily -eq "IPv4" -and $UString.InterfaceAlias -notmatch "Bluetooth" )
            { $UAdapter = Get-NetAdapter $UString.InterfaceAlias | Select-Object -ExpandProperty InterfaceDescription }
            else { $UAdapter = "" }

            If (!($UAdapter -le ".{2}")) {
                $checkSW = '[ ' + $Numb + ' ]'

                If ($NrSWList -eq $checkSW -and $loopbreaker -eq "false") {
                    function Convert-ToTable {
                        param([Parameter(Position = 0, Mandatory = $true)] [string]$Variable)
         
                        $List = @()
                        ForEach ($line in $($Variable -split "`r`n")) {
                            $List += $line
                        }
                        return $List
                    }
                    Do {

                        $UIPGWA = (Get-NetIPConfiguration -InterfaceAlias $Ustring.InterfaceAlias | Select-Object -ExpandProperty IPv4DefaultGateway).NextHop
                        $UAdapter = Get-NetAdapter -InterfaceAlias $UString.InterfaceAlias | Select-Object -ExpandProperty InterfaceDescription
                        $UIP4vA = Get-NetIPAddress -InterfaceAlias $UString.InterfaceAlias -AddressFamily "IPv4" | Select-Object -ExpandProperty IPv4Address
    
                        [string]$DHCP_check = Get-NetIPAddress -InterfaceAlias $UString.InterfaceAlias -AddressFamily "IPv4" | Select-Object -ExpandProperty "PrefixOrigin"
                        [string]$DHCP_active = $DHCP_check.ToString().ToUpper()

                        $UIPdnsA = Get-DnsClientServerAddress -InterfaceAlias $UString.InterfaceAlias -AddressFamily "IPv4" | Select-Object -ExpandProperty ServerAddresses
                        [byte]$Global:Suffix = Get-NetIPAddress -InterfaceAlias $UString.InterfaceAlias -AddressFamily "IPv4" | Select-Object -ExpandProperty "PrefixLength"

                        Conv 1
                        Conv 2
                        Conv 3
                        Conv 4

                        $SUBMASK = -join ($Global:Sequ1, ".", $Global:Sequ2, ".", $Global:Sequ3, ".", $Global:Sequ4) 
        
                        Clear-Host
                        Write-Host ""
                        Write-Host "Networkcard changer"
                        Write-Host "-------------------"
                        Write-Host ""
                        Write-Host "Please select follow Mode for Adapter " -NoNewline
                        Write-Host "" -NoNewline
                        Write-Host $UAdapter -ForegroundColor yellow
                        Write-Host "_______________________________________________________________________________"
                        Write-Host ""
                        Write-Host "Current configuration:"
                        Write-Host "IP-Address:" `t -NoNewline
                        Write-Host $UIP4vA  -ForegroundColor Yellow -NoNewline
                        Write-Host " (" -NoNewline
                        Write-Host $DHCP_active -ForegroundColor Green -NoNewline
                        Write-Host ")"
                        Write-Host "Subnetmask:" `t -NoNewline
                        Write-Host $SUBMASK  -ForegroundColor Yellow
                        Write-Host "Gateway:" `t -NoNewline
                        Write-Host $UIPGWA -ForegroundColor Yellow
                        Write-Host "DNS-Address:" `t -NoNewline
                        Write-Host $UIPdnsA  -ForegroundColor Yellow
                        Write-Host "_______________________________________________________________________________"
                    
                        $mode = Read-Host "Select (D)HCP, (S)tatic IP, (R)estart, (C)lear Networkcard: "
                    } While (!($mode -eq 'd' -or $mode -eq 's' -or $mode -eq 'r' -or $mode -eq 'c'))
        
                    #####################################################################################################################################
                    If ($mode -eq 'd') {

                        $interface = Get-NetIPInterface -InterfaceAlias $UString.InterfaceAlias -AddressFamily IPv4
                        Remove-NetIPAddress -InterfaceAlias $UString.InterfaceAlias -Confirm:$false
                        $interface | Remove-NetRoute -AddressFamily IPv4 -Confirm:$false
                        $interface | Set-NetIPInterface -Dhcp Enabled
                        $interface | Set-DnsClientServerAddress -ResetServerAddresses
                        Get-NetAdapter -Name $UString.InterfaceAlias | Restart-NetAdapter
                     
                        config
                    }
                    #####################################################################################################################################
                    elseif ($mode -eq 's') {
           
                        Do { $Nipv4 = Read-Host "Enter new IPv4-Address: " } While (($Nipv4 -le ".{6}"))
                        Do { $NSNM = Read-Host "Enter new Subnetmask: " } While (($NSNM -le ".{6}"))
                        Do { $NSGW = Read-Host "Enter new Standardgateway: " } While (($NSGW -le ".{6}"))
                        $NDNS1 = Read-Host "Enter new Primary DNS-Address: "
                        $NDNS2 = Read-Host "Enter new Secundary DNS-Address: "
                                               
                        $NSNM = ConvertTo-MaskLength $NSNM

                        $interface = Get-NetIPInterface -InterfaceAlias $UString.InterfaceAlias -AddressFamily IPv4
                        Remove-NetIPAddress -InterfaceAlias $UString.InterfaceAlias -Confirm:$false | Out-Null
                        $interface | Remove-NetRoute -AddressFamily IPv4 -Confirm:$false | Out-Null
                        
                        Set-NetIPInterface -InterfaceAlias $UString.InterfaceAlias -Dhcp Disabled -AddressFamily IPv4
                        New-NetIPAddress -InterfaceAlias $UString.InterfaceAlias -IPAddress $Nipv4 -PrefixLength $NSNM -DefaultGateway $NSGW -AddressFamily IPv4
                        Set-DnsClientServerAddress -InterfaceAlias $UString.InterfaceAlias -ServerAddresses $NDNS1, $NDNS2
     
                        config
                    }
                    #####################################################################################################################################
                    elseif ($mode -eq 'r') {
                        Get-NetAdapter -Name $UString.InterfaceAlias | Restart-NetAdapter

                        config
                    }
                    elseif ($mode -eq 'c') {
                        function Remove-UnknownDevice {
                            $NarrowByClass = "Net"
                            $Force = $True

                            Param(
                                [array]$NarrowByClass,
                                [switch]$Force
                            )

                            $removeDevices = $true

                            function Filter-Device {
                                Param (
                                    [System.Object]$dev
                                )
                                $Class = $dev.Class
                                $FriendlyName = $dev.FriendlyName
                                $matchFilter = $false


                                if (($matchFilter -eq $false) -and ($NarrowByClass -ne $null)) {
                                    $shouldInclude = $false
                                    foreach ($ClassFilter in $NarrowByClass) {
                                        if ($ClassFilter -eq $Class) {
                                            $shouldInclude = $true
                                            break
                                        }
                                    }
                                    $matchFilter = !$shouldInclude
                                }

                                return $matchFilter
                            }

                            function Filter-Devices {
                                Param (
                                    [array]$devices
                                )
                                $filteredDevices = @()
                                foreach ($dev in $devices) {
                                    $matchFilter = Filter-Device -Dev $dev
                                    if ($matchFilter -eq $false) {
                                        $filteredDevices += @($dev)
                                    }
                                }
                                return $filteredDevices
                            }

                            $setupapi = @"
using System;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
namespace Win32
{
    public static class SetupApi
    {
         // 1st form using a ClassGUID only, with Enumerator = IntPtr.Zero
        [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SetupDiGetClassDevs(
           ref Guid ClassGuid,
           IntPtr Enumerator,
           IntPtr hwndParent,
           int Flags
        );
     
        // 2nd form uses an Enumerator only, with ClassGUID = IntPtr.Zero
        [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SetupDiGetClassDevs(
           IntPtr ClassGuid,
           string Enumerator,
           IntPtr hwndParent,
           int Flags
        );
         
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiEnumDeviceInfo(
            IntPtr DeviceInfoSet,
            uint MemberIndex,
            ref SP_DEVINFO_DATA DeviceInfoData
        );
     
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern bool SetupDiDestroyDeviceInfoList(
            IntPtr DeviceInfoSet
        );
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiGetDeviceRegistryProperty(
            IntPtr deviceInfoSet,
            ref SP_DEVINFO_DATA deviceInfoData,
            uint property,
            out UInt32 propertyRegDataType,
            byte[] propertyBuffer,
            uint propertyBufferSize,
            out UInt32 requiredSize
        );
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool SetupDiGetDeviceInstanceId(
            IntPtr DeviceInfoSet,
            ref SP_DEVINFO_DATA DeviceInfoData,
            StringBuilder DeviceInstanceId,
            int DeviceInstanceIdSize,
            out int RequiredSize
        );
 
     
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiRemoveDevice(IntPtr DeviceInfoSet,ref SP_DEVINFO_DATA DeviceInfoData);
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct SP_DEVINFO_DATA
    {
       public uint cbSize;
       public Guid classGuid;
       public uint devInst;
       public IntPtr reserved;
    }
    [Flags]
    public enum DiGetClassFlags : uint
    {
        DIGCF_DEFAULT = 0x00000001, // only valid with DIGCF_DEVICEINTERFACE
        DIGCF_PRESENT = 0x00000002,
        DIGCF_ALLCLASSES = 0x00000004,
        DIGCF_PROFILE = 0x00000008,
        DIGCF_DEVICEINTERFACE = 0x00000010,
    }
    public enum SetupDiGetDeviceRegistryPropertyEnum : uint
    {
         SPDRP_DEVICEDESC = 0x00000000, // DeviceDesc (R/W)
         SPDRP_HARDWAREID = 0x00000001, // HardwareID (R/W)
         SPDRP_COMPATIBLEIDS = 0x00000002, // CompatibleIDs (R/W)
         SPDRP_UNUSED0 = 0x00000003, // unused
         SPDRP_SERVICE = 0x00000004, // Service (R/W)
         SPDRP_UNUSED1 = 0x00000005, // unused
         SPDRP_UNUSED2 = 0x00000006, // unused
         SPDRP_CLASS = 0x00000007, // Class (R--tied to ClassGUID)
         SPDRP_CLASSGUID = 0x00000008, // ClassGUID (R/W)
         SPDRP_DRIVER = 0x00000009, // Driver (R/W)
         SPDRP_CONFIGFLAGS = 0x0000000A, // ConfigFlags (R/W)
         SPDRP_MFG = 0x0000000B, // Mfg (R/W)
         SPDRP_FRIENDLYNAME = 0x0000000C, // FriendlyName (R/W)
         SPDRP_LOCATION_INFORMATION = 0x0000000D, // LocationInformation (R/W)
         SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E, // PhysicalDeviceObjectName (R)
         SPDRP_CAPABILITIES = 0x0000000F, // Capabilities (R)
         SPDRP_UI_NUMBER = 0x00000010, // UiNumber (R)
         SPDRP_UPPERFILTERS = 0x00000011, // UpperFilters (R/W)
         SPDRP_LOWERFILTERS = 0x00000012, // LowerFilters (R/W)
         SPDRP_BUSTYPEGUID = 0x00000013, // BusTypeGUID (R)
         SPDRP_LEGACYBUSTYPE = 0x00000014, // LegacyBusType (R)
         SPDRP_BUSNUMBER = 0x00000015, // BusNumber (R)
         SPDRP_ENUMERATOR_NAME = 0x00000016, // Enumerator Name (R)
         SPDRP_SECURITY = 0x00000017, // Security (R/W, binary form)
         SPDRP_SECURITY_SDS = 0x00000018, // Security (W, SDS form)
         SPDRP_DEVTYPE = 0x00000019, // Device Type (R/W)
         SPDRP_EXCLUSIVE = 0x0000001A, // Device is exclusive-access (R/W)
         SPDRP_CHARACTERISTICS = 0x0000001B, // Device Characteristics (R/W)
         SPDRP_ADDRESS = 0x0000001C, // Device Address (R)
         SPDRP_UI_NUMBER_DESC_FORMAT = 0X0000001D, // UiNumberDescFormat (R/W)
         SPDRP_DEVICE_POWER_DATA = 0x0000001E, // Device Power Data (R)
         SPDRP_REMOVAL_POLICY = 0x0000001F, // Removal Policy (R)
         SPDRP_REMOVAL_POLICY_HW_DEFAULT = 0x00000020, // Hardware Removal Policy (R)
         SPDRP_REMOVAL_POLICY_OVERRIDE = 0x00000021, // Removal Policy Override (RW)
         SPDRP_INSTALL_STATE = 0x00000022, // Device Install State (R)
         SPDRP_LOCATION_PATHS = 0x00000023, // Device Location Paths (R)
         SPDRP_BASE_CONTAINERID = 0x00000024 // Base ContainerID (R)
    }
}
"@


                            Add-Type -TypeDefinition $setupapi

                            #Array for all removed devices report
                            $removeArray = @()
                            #Array for all devices report
                            $array = @()

                            $setupClass = [Guid]::Empty
                            #Get all devices
                            $devs = [Win32.SetupApi]::SetupDiGetClassDevs([ref]$setupClass, [IntPtr]::Zero, [IntPtr]::Zero, [Win32.DiGetClassFlags]::DIGCF_ALLCLASSES)

                            #Initialise Struct to hold device info Data
                            $devInfo = new-object Win32.SP_DEVINFO_DATA
                            $devInfo.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf($devInfo)

                            #Device Counter
                            $devCount = 0
                            #Enumerate Devices
                            while ([Win32.SetupApi]::SetupDiEnumDeviceInfo($devs, $devCount, [ref]$devInfo)) {

                                #Will contain an enum depending on the type of the registry Property, not used but required for call
                                $propType = 0
                                #Buffer is initially null and buffer size 0 so that we can get the required Buffer size first
                                [byte[]]$propBuffer = $null
                                $propBufferSize = 0
                                #Get Buffer size
                                [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_FRIENDLYNAME, [ref]$propType, $propBuffer, 0, [ref]$propBufferSize) | Out-null
                                #Initialize Buffer with right size
                                [byte[]]$propBuffer = New-Object byte[] $propBufferSize

                                #Get HardwareID
                                $propTypeHWID = 0
                                [byte[]]$propBufferHWID = $null
                                $propBufferSizeHWID = 0
                                [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_HARDWAREID, [ref]$propTypeHWID, $propBufferHWID, 0, [ref]$propBufferSizeHWID) | Out-null
                                [byte[]]$propBufferHWID = New-Object byte[] $propBufferSizeHWID

                                #Get DeviceDesc (this name will be used if no friendly name is found)
                                $propTypeDD = 0
                                [byte[]]$propBufferDD = $null
                                $propBufferSizeDD = 0
                                [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_DEVICEDESC, [ref]$propTypeDD, $propBufferDD, 0, [ref]$propBufferSizeDD) | Out-null
                                [byte[]]$propBufferDD = New-Object byte[] $propBufferSizeDD

                                #Get Install State
                                $propTypeIS = 0
                                [byte[]]$propBufferIS = $null
                                $propBufferSizeIS = 0
                                [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_INSTALL_STATE, [ref]$propTypeIS, $propBufferIS, 0, [ref]$propBufferSizeIS) | Out-null
                                [byte[]]$propBufferIS = New-Object byte[] $propBufferSizeIS

                                #Get Class
                                $propTypeCLSS = 0
                                [byte[]]$propBufferCLSS = $null
                                $propBufferSizeCLSS = 0
                                [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_CLASS, [ref]$propTypeCLSS, $propBufferCLSS, 0, [ref]$propBufferSizeCLSS) | Out-null
                                [byte[]]$propBufferCLSS = New-Object byte[] $propBufferSizeCLSS
                                [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_CLASS, [ref]$propTypeCLSS, $propBufferCLSS, $propBufferSizeCLSS, [ref]$propBufferSizeCLSS)  | out-null
                                $Class = [System.Text.Encoding]::Unicode.GetString($propBufferCLSS)

                                #Read FriendlyName property into Buffer
                                if (![Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_FRIENDLYNAME, [ref]$propType, $propBuffer, $propBufferSize, [ref]$propBufferSize)) {
                                    [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_DEVICEDESC, [ref]$propTypeDD, $propBufferDD, $propBufferSizeDD, [ref]$propBufferSizeDD)  | out-null
                                    $FriendlyName = [System.Text.Encoding]::Unicode.GetString($propBufferDD)
                                    #The friendly Name ends with a weird character
                                    if ($FriendlyName.Length -ge 1) {
                                        $FriendlyName = $FriendlyName.Substring(0, $FriendlyName.Length - 1)
                                    }
                                }
                                else {
                                    #Get Unicode String from Buffer
                                    $FriendlyName = [System.Text.Encoding]::Unicode.GetString($propBuffer)
                                    #The friendly Name ends with a weird character
                                    if ($FriendlyName.Length -ge 1) {
                                        $FriendlyName = $FriendlyName.Substring(0, $FriendlyName.Length - 1)
                                    }
                                }

                                #InstallState returns true or false as an output, not text
                                $InstallState = [Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_INSTALL_STATE, [ref]$propTypeIS, $propBufferIS, $propBufferSizeIS, [ref]$propBufferSizeIS)

                                # Read HWID property into Buffer
                                if (![Win32.SetupApi]::SetupDiGetDeviceRegistryProperty($devs, [ref]$devInfo, [Win32.SetupDiGetDeviceRegistryPropertyEnum]::SPDRP_HARDWAREID, [ref]$propTypeHWID, $propBufferHWID, $propBufferSizeHWID, [ref]$propBufferSizeHWID)) {
                                    #Ignore if Error
                                    $HWID = ""
                                }
                                else {
                                    #Get Unicode String from Buffer
                                    $HWID = [System.Text.Encoding]::Unicode.GetString($propBufferHWID)
                                    #trim out excess names and take first object
                                    $HWID = $HWID.split([char]0x0000)[0].ToUpper()
                                }

                                #all detected devices list
                                $device = New-Object System.Object
                                $device | Add-Member -type NoteProperty -name FriendlyName -value $FriendlyName
                                $device | Add-Member -type NoteProperty -name HWID -value $HWID
                                $device | Add-Member -type NoteProperty -name InstallState -value $InstallState
                                $device | Add-Member -type NoteProperty -name Class -value $Class
                                if ($array.count -le 0) {
                                    sleep 1
                                }
                                $array += @($device)

                                if ($removeDevices -eq $true) {
                                    #we want to remove devices so let's check the filters...
                                    $matchFilter = Filter-Device -Dev $device

                                    if ($InstallState -eq $False) {
                                        if ($matchFilter -eq $false) {
                                            $message = "Attempting to remove device $FriendlyName"
                                            $confirmed = $false
                                            if (!$Force -eq $true) {
                                                $question = 'Are you sure you want to proceed?'
                                                $choices = '&Yes', '&No'
                                                $decision = $Host.UI.PromptForChoice($message, $question, $choices, 1)
                                                if ($decision -eq 0) {
                                                    $confirmed = $true
                                                }
                                            }
                                            else {
                                                $confirmed = $true
                                            }
                                            if ($confirmed -eq $true) {
                                                $removeObj = New-Object System.Object
                                                $removeObj | Add-Member -type NoteProperty -name FriendlyName -value $FriendlyName
                                                $removeObj | Add-Member -type NoteProperty -name HWID -value $HWID
                                                $removeObj | Add-Member -type NoteProperty -name InstallState -value $InstallState
                                                $removeObj | Add-Member -type NoteProperty -name Class -value $Class
                                                $removeArray += @($removeObj)
                                                if ([Win32.SetupApi]::SetupDiRemoveDevice($devs, [ref]$devInfo)) {
              
                                                }
                                                else {
               
                                                }
                                            }
                                            else {
               
                                            }
                                        }
                                        else {
          
                                        }
                                    }
                                }
                                $devcount++
                            }


                        }
                        function Search-DeviveManager() {
 
                            [string]$SourceCode = @"
  
    using System.Runtime.InteropServices;
  
    using System;
  
    
  
    namespace check.devices
  
    {
  
        // These are the native win32 methods that we require
  
        internal static class NativeMethods
  
        {
  
            [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CM_Locate_DevNode_Ex", CharSet = CharSet.Auto)]
  
            public static extern UInt32 CM_Locate_DevNode_Ex(ref UInt32 DevInst, IntPtr DeviceID, UInt64 Flags, IntPtr Machine);
  
  
  
            [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CM_Reenumerate_DevNode_Ex", CharSet = CharSet.Auto)]
  
            public static extern UInt32 CM_Reenumerate_DevNode_Ex(UInt32 DevInst, UInt64 Flags, IntPtr Machine);
  
  
  
            [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CMP_WaitNoPendingInstallEvents", CharSet = CharSet.Auto)]
  
            public static extern UInt32 CMP_WaitNoPendingInstallEvents(UInt32 TimeOut);
  
        }
  
        
  
        // This class houses the public methods that we'll use from powershell
  
        public static class StaticMethods
  
        {
  
        
  
            public const UInt32 CR_SUCCESS = 0;
  
            public const UInt64 CM_REENUMERATE_SYNCHRONOUS = 1;
  
            public const UInt64 CM_LOCATE_DEVNODE_NORMAL = 0;
  
            
  
            public static UInt32 RescanAllDevices()
  
            {
  
                //only connect to local device nodes
  
                UInt32 ResultCode = 0;
  
                IntPtr LocalMachineInstance = IntPtr.Zero;
  
                UInt32 DeviceInstance = 0;
  
                UInt32 PendingTime = 30000;
  
  
  
                ResultCode = NativeMethods.CM_Locate_DevNode_Ex(ref DeviceInstance, IntPtr.Zero, CM_LOCATE_DEVNODE_NORMAL, LocalMachineInstance);
  
                if (CR_SUCCESS == ResultCode)
  
                {
  
                    ResultCode = NativeMethods.CM_Reenumerate_DevNode_Ex(DeviceInstance, CM_REENUMERATE_SYNCHRONOUS, LocalMachineInstance);
  
                    ResultCode = NativeMethods.CMP_WaitNoPendingInstallEvents(PendingTime);
  
                }
  
                return ResultCode;
  
            }
  
        }
  
    }
  
"@


                            add-type -TypeDefinition $SourceCode

                            [check.devices.staticmethods]::RescanAllDevices() | Out-Null
                            [check.devices.staticmethods]::RescanAllDevices() | Out-Null
                        }

                        #FILTER DEVICE
                        $FindPNPFilter = (Get-NetAdapter | Where-Object { $_.Name -eq $UString.InterfaceAlias }).InterfaceDescription
                        $Dev = Get-PnpDevice -class Net | Where-Object { $_.FriendlyName -eq $FindPNPFilter } | Select FriendlyName, InstanceId 
         


                        ipconfig /flushdns | Out-Null
                        netsh winsock reset | Out-Null
                        #netsh int ip reset | Out-Null
                        #netsh interface ip delete arpcache | Out-Null
                            
                        #REMOVE NIC FROM REGISTRY
                        $RemoveKey = "HKLM:\SYSTEM\CurrentControlSet\Enum\$($Dev.InstanceId)"
                        Get-Item $RemoveKey | Select-Object -ExpandProperty Property | % { Remove-ItemProperty -Path $RemoveKey -Name $_ } 

                        #Delete all Unknown Devices from Device-Manager
                        Remove-UnknownDevice

                        #Search of lost Devices
                        Search-DeviveManager
                  
                        config
                    }

                    $loopbreaker = "true"
                }
                $Numb = $Numb + 1
            }
        }
    } While ($true)
}

Marli-net