Сценарий Powershell Изменение свойств DNS, работающее в 32-битной системе, но не работающее в 64-битной

Это сценарий, который изменяет конфигурацию свойств DNS, таких как установка IP-адреса, шлюза по умолчанию и адреса DNS-сервера, которые можно найти в Панели управления -> Центр управления сетями и общим доступом -> выбрать адаптер -> Свойства -> Интернет-протокол версии 4. (TCP/IPv4).введите здесь описание изображения

Этот скрипт отлично работает на системах windows 7 32-bit и windows 10 32-bit, но по какой-то причине он не работает на windows 7 64 bit. Всякий раз, когда я пытаюсь изменить IP-адрес, он выдает error code 97, то есть Interface not configurable. Если я использую функцию адаптера непосредственно в командной строке PowerShell, например $adapter = (get-wmiobject win32_networkadapterconfiguration | where-object {$_.index -eq 7}) $adapter.EnableStatic("192.168.1.50", "255.255.255.0"), она работает в пользовательском интерфейсе командной строки Powershell. Я не могу понять, почему и как это происходит?

ОБНОВЛЕНИЕ:

Я попытался отладить код и обнаружил, что по какой-то причине не могу получить AdapterIndex из hash_Table network_info, например

$network_info = Get-IPAdapterInformation 
[string]$AdapterName = $network_info.AdapterName
[string]$AdapterInterfaceIndex = $network_info.AdapterInterfaceIndex
[string]$AdapterIndex = $network_info.AdapterIndex
cls
#function to get Adapter Info based on Mac-Address
function Get-IPAdapterInformation{
#    [CmdletBinding()]
    $AdapterInfo = @{}
#    $MyMacAddress = "00:15:5D:00:A3:07"
    $MyMacAddress = Read-Host "Enter Mac Address of Adapter"
    $MyMacAddress = $MyMacAddress.Trim()
    Try { $IPconfigset = Get-WmiObject Win32_NetworkAdapterConfiguration -Namespace "root\CIMv2" -ErrorAction:Stop  | ? {$_.IPEnabled -and ($_.MACAddress -ne $null)} } Catch { return $IPs }
    foreach ($ip in $IPconfigset) {
        if($ip.MACAddress -eq $MyMacAddress){
            $i = New-Object PSObject | Select-Object Index, InterfaceIndex, IPAddress, Subnet, Name, DeviceName, MACAddress, DNSSearchOrder, Gateway, Status
            $i.Index = $ip.Index
            $i.InterfaceIndex = $ip.InterfaceIndex
            $i.IPAddress = $ip.IPAddress[0]
            $i.Subnet = $ip.IPSubnet[0]
            $i.DeviceName = $ip.Description
            $i.MACAddress = $ip.MACAddress
            $i.DNSSearchOrder = $ip.DNSServerSearchOrder
            $i.Gateway = $ip.DefaultIPGateway
            $i.Name = (Get-WmiObject win32_networkadapter -ErrorAction:SilentlyContinue | ? {$_.Name -eq $i.DeviceName}).netconnectionid
            $i.Status = (Get-WmiObject win32_networkadapter -ErrorAction:SilentlyContinue | ? {$_.Name -eq $i.DeviceName}).NetConnectionStatus
            $AdapterInfo.add('AdapterName', $i.Name)
            $AdapterInfo.add('AdapterInterfaceDescription', $i.DeviceName)
            $AdapterInfo.add('AdapterInterfaceIndex', $i.InterfaceIndex)
            $AdapterInfo.add('AdapterIndex', $i.Index)
        }
      }
    if($AdapterInfo -ne $null){
        Write-Host "Adapter Found!" -ForegroundColor Green
        Write-Host "Adapter Name:"$AdapterInfo.AdapterName -ForegroundColor Green
        Write-Host "Adapter InterfaceIndex:"$AdapterInfo.AdapterInterfaceIndex -ForegroundColor Green
        Write-Host "Adapter Interface Description:"$AdapterInfo.AdapterInterfaceDescription -ForegroundColor Green
        Write-Host "Adapter Index:"$AdapterInfo.AdapterIndex -ForegroundColor Green        
    }else{
        Write-Host "No Adapter found with given MacAddress" -ForegroundColor Ref
    }
    return $AdapterInfo
}


#====================================================================
# STEP #2: SETUP NETWORK
#====================================================================
Write-Host "Available Network Adapters on this Device:" -ForegroundColor Green
Get-WmiObject Win32_networkAdapter | ?{$_.MACAddress -ne $null} | Select NetConnectionID, Name, MACAddress, Description, InterfaceIndex, NetConnectionStatus

$network_info = Get-IPAdapterInformation
#$network_info
[string]$AdapterName = $network_info.AdapterName
[string]$AdapterInterfaceIndex = $network_info.AdapterInterfaceIndex
[string]$AdapterIndex = $network_info.AdapterIndex


#Returns StatusCode Description based on given status code
function Get-StatusCodeDescripton($StatusCode){
    Switch($StatusCode){
        0{
            return "Successful completion, no reboot required"
        }1{
            return "Successful completion, reboot required"
        }64{         
            return "Method not supported on this platform"
        }65{
            return "Unknown failure"
        }66{
            return "Invalid subnet mask"
        }67{
            return "An error occurred while processing an Instance that was returned"
        }68{
            return "Invalid input parameter"
        }69{
            return "More than 5 gateways specified"
        }70{
            return "Invalid IP address"
        }71{
            return "Invalid gateway IP address"
        }72{
            return "An error occurred while accessing the Registry for the requested information"
        }73{
            return "Invalid domain name"
        }74{
            return "Invalid host name"
        }75{
            return "No primary/secondary WINS server defined"
        }76{
            return "Invalid file"
        }77{
            return "Invalid system path"
        }78{
            return "File copy failed"
        }79{
            return "Invalid security parameter"
        }80{
            return "Unable to configure TCP/IP service"
        }81{
            return "Unable to configure DHCP service"
        }82{
            return "Unable to renew DHCP lease"
        }83{
            return "Unable to release DHCP lease"
        }84{
            return "IP not enabled on adapter"
        }85{
            return "IPX not enabled on adapter"
        }86{
            return "Frame/network number bounds error"
        }87{
            return "Invalid frame type"
        }88{
            return "Invalid network number"
        }89{
            return "Duplicate network number"
        }90{
            return "Parameter out of bounds"
        }91{
            return "Access denied"
        }92{
            return "Out of memory"
        }93{
            return "Already exists"
        }94{
            return "Path, file or object not found"
        }95{
            return "Unable to notify service"
        }96{
            return "Unable to notify DNS service"
        }97{
            return "Interface not configurable"
        }98{
            return "Not all DHCP leases could be released/renewed"
        }100{
            return "DHCP not enabled on adapter"
        }101{
            return "Some error occured!"       
        }default{
            return "Some Unknown error occurred!"
        }
    }
}

#Set IP address(Input: IPAddrss, DefaultGateway, SubnetMask(Optional))
function Set-IPAddress{
    [CmdletBinding()]
    Param(
        #IP Address
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=0)]
        [String]$IPAddress,
        #Default Gateway
        [Parameter(Mandatory=$true, 
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [String]$DefaultGateway
    )
    $IPAddress
    $SubNetMask = Read-Host "Enter Subnet Mask[Default 255.255.255.0]"
    if(-not $SubNetMask){
        $SubNetMask ="255.255.255.0"
    }
    $SubNetMask
    $adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
    $IPandSubnetMaskResult = $adapter.EnableStatic($IPAddress, $SubNetMask) #IPAddress, Subnet Mask    
    $IPandSubnetMaskResultCode = $IPandSubnetMaskResult.ReturnValue
    $IPandSubnetMaskResultCode
    $IPandSubnetMaskResultDesciption = Get-StatusCodeDescripton($IPandSubnetMaskResultCode)
    if(($IPandSubnetMaskResultCode -eq 0) -or ($IPandSubnetMaskResultCode -eq 1)){
        Write-Host $IPandSubnetMaskResultDesciption -ForegroundColor Green
        Write-Host "[SUCCESS] Changed Static IP Address to: $($IPAddress)." -ForegroundColor Green         
    }else{
        Write-Host $IPandSubnetMaskResultDesciption -ForegroundColor Red
    }
    $GatewayResult = $adapter.SetGateways($DefaultGateway)
    $GatewayResultCode = $GatewayResult.ReturnValue
    $GatewayResultDescription =  Get-StatusCodeDescripton($GatewayResultCode)
    if(($GatewayResultCode -eq 0) -or ($GatewayResultCode -eq 1)){
        Write-Host $GatewayResultDescription -ForegroundColor Green
        Write-Host "[SUCCESS] Changed Default GAteway to: $($DefaultGateway)." -ForegroundColor Green    
    }else{
        Write-Host $GatewayResultDescription -ForegroundColor Red
        Write-Host "An Error occurred!" -ForegroundColor Red
    }
    Sleep -Seconds 4 #sometimes setting instantly IP address gives error 67.
}

#Set DNS Server Address(Input:PrimaryDNSAddress, SecondaryDNSAddress(Optional))
function Set-DNSServerAdddress{
    [CmdletBinding()]
    Param(
        #Primary DNS Server Address
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=0)]
        [String]$PrimaryDNSAddress
    )
    $SecondaryDNSAddress = Read-Host "Enter Secondary DNS Address[Optional]"
    $adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
    if($SecondaryDNSAddress){
        $SetDNSServerAddressResult = $adapter.SetDNSServerSearchOrder(@($PrimaryDNSAddress, $SecondaryDNSAddress))
    }else{
        $SetDNSServerAddressResult = $adapter.SetDNSServerSearchOrder(@($PrimaryDNSAddress))
    }
    $SetDNSServerAddressResultCode = $SetDNSServerAddressResult.ReturnValue
    $SetDNSServerAddressResultDescription =  Get-StatusCodeDescripton($SetDNSServerAddressResult)
    if(($SetDNSServerAddressResultCode -eq 0) -or ($SetDNSServerAddressResultCode -eq 1)){
        Write-Host $SetDNSServerAddressResultDescription -ForegroundColor Green
        Write-Host "[SUCCESS] Set DNS Servers to: $($PrimaryDNSAddress), $($SecondaryDNSAddress)." -ForegroundColor Green    
    }else{
        Write-Host $GatewayResultDescription -ForegroundColor Red
        Write-Host "An Error occurred!" -ForegroundColor Red
    }    
    Sleep -Seconds 4
}


function Set-DNSSererAddressAutomatically{
    $userInput = Read-Host "Do you want to set DNS Server Address Automatically? [y]Yes  [n]No[Default NO]"
    if($userInput -eq "y" -or $userInput -eq "yes"){       
        $adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
        $SetDNSServerAddressAutomaticallyResult = $adapter.SetDNSServerSearchOrder()
        $SetDNSServerAddressAutomaticallyResultCode = $SetDNSServerAddressAutomaticallyResult.ReturnValue
        $SetDNSServerAddressAutomaticallyResultDescription =  Get-StatusCodeDescripton($SetDNSServerAddressAutomaticallyResultCode)
        if(($SetDNSServerAddressAutomaticallyResultCode -eq 0) -or ($SetDNSServerAddressAutomaticallyResultCode -eq 1)){
            Write-Host $SetDNSServerAddressAutomaticallyResultDescription -ForegroundColor Green
            Write-Host "[SUCCESS] Set DNS Servers Automatically." -ForegroundColor Green    
        }else{
            Write-Host $SetDNSServerAddressAutomaticallyResultDescription -ForegroundColor Red
            Write-Host "An Error occurred!" -ForegroundColor Red
        }    
    }else{
        Write-Warning "You selected NO"
    }
    Sleep -Seconds 4
}

function Set-IPAddressAutomatically{
    $userInput = Read-Host "Set IP Automatically? [y]Yes  [n]No[Default NO]"
    if($userInput -eq "y" -or $userInput -eq "yes"){       
        $adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
        $SetIPAddressAutomaticallyResult = $adapter.EnableDHCP()
        $SetIPAddressAutomaticallyResultCode = $SetIPAddressAutomaticallyResult.ReturnValue
        $SetIPAddressAutomaticallyResultDescription =  Get-StatusCodeDescripton($SetIPAddressAutomaticallyResultCode)
        if(($SetIPAddressAutomaticallyResultCode -eq 0) -or ($SetIPAddressAutomaticallyResultCode -eq 1)){
            Write-Host $SetIPAddressAutomaticallyResultDescription -ForegroundColor Green
            Write-Host "[SUCCESS] Set IP Addresss Automatically." -ForegroundColor Green    
        }else{
            Write-Host $SetIPAddressAutomaticallyResultDescription -ForegroundColor Red
            Write-Host "An Error occurred!" -ForegroundColor Red
        }    
    }else{
        Write-Warning "You selected NO"
    }
    Sleep -Seconds 4
}
#Set-IPAddress #working
#Set-DNSServerAdddress #not working with2nd DNS Server Address
#Set-DNSSererAddressAutomatically # working
#Set-IPAddressAutomatically #working


$choices = "Select Operation:
    0. Print Choices
    1. Set IP Address and Default Gateway
    2. Set DNS Server Address
    3. Set IP Address Automatically
    4. Set DNS Server Address Automatically
    t. exit/terminate
"
$status = $true
while($status){
    $choice = Read-Host "Select choice: $choices"
    $choice
    switch($choice){
        0{
            Write-Host " ==> Print choices: $choices" -ForeGround Green
            break
        }
        1{
            Write-Host " ==> Set IP Address and Default Gateway" -ForeGround Green
            Set-IPAddress
            break
        }
        2{
            Write-Host " ==> Set DNS Server Address" -ForeGround Green
            Set-DNSServerAdddress
            break
        }
        3{
            Write-Host " ==> Set IP Address Automatically" -ForeGround Green
            Set-IPAddressAutomatically
            break
        }
        
        4{
            Write-Host " ==> Set DNS Server Address Automatically"
            Set-DNSSererAddressAutomatically
            break
        }            
        t{
            Write-Host " ==> Exit" -ForeGround Green
            
            $status = $false
        }                    
        }
}

#Index          : 7
#InterfaceIndex : 11
#IPAddress      : 192.168.234.197
#Subnet         : 255.255.240.0
#Name           : Local Area Connection
#DeviceName     : Microsoft Virtual Machine Bus Network Adapter
#MACAddress     : 00:15:5D:00:A3:07
#DNSSearchOrder : {192.168.224.1}
#Gateway        : {192.168.224.1}
#Status         : 2



person Sheraram_Prajapat    schedule 13.06.2021    source источник
comment
Похоже, проблема в вашей функции Set-DNSServerAddress: вы получаете код возврата и не отправляете его в свою функцию. Get-StatusCodeDescription: вы должны заменить: $SetDNSServerAddressResultCode = $SetDNSServerAddressResult.ReturnValue с: $SetDNSServerAddressResultCode = $SetDNSServerAddressResult.ReturnValue $SetDNSServerAddressResultDescription = Get-StatusCodeDescripton($SetDNSServerAddressResultCode)   -  person Brice    schedule 14.06.2021
comment
да. Спасибо. Я попытался отладить код и обнаружил, что по какой-то причине не могу получить AdapterIndex из hash_Table network_info, например $network_info = Get-IPAdapterInformation [string]$AdapterName = $network_info.AdapterName [string]$AdapterInterfaceIndex = $network_info.AdapterInterfaceIndex [ строка]$AdapterIndex = $network_info.AdapterIndex   -  person Sheraram_Prajapat    schedule 15.06.2021
comment
Для индексов $i.InterfaceIndex = $ip.InterfaceIndex должно быть $i.InterfaceIndex = $ip.Index   -  person Cpt.Whale    schedule 16.06.2021
comment
@Cpt.Whale, Index и InterfaceIndex — это две разные вещи. Кроме того, когда я печатаю $network_info(словарь), он печатает ключ, значение и имя присутствующих в нем элементов, но когда я пытаюсь получить этот элемент, он не получает доступ к этому значению.   -  person Sheraram_Prajapat    schedule 17.06.2021
comment
Да, думаю, кофе нужен. Я пошел дальше и запустил весь сценарий как есть до того места, где у вас возникли проблемы с $network_info.AdapterIndex на машине с 64-разрядной версией Windows 7, и я могу без проблем вытащить $AdapterIndex, так что это может быть просто та виртуальная машина. ? Я бы порекомендовал использовать его в качестве параметра для других ваших функций, а не использовать в основном глобальную переменную. Set-DNSServerAdddress и Set-DNSSererAddressAutomatically написаны с ошибками, но это не проблема.   -  person Cpt.Whale    schedule 17.06.2021
comment
спасибо @Cpt.Whale. Знаете ли вы, как я могу исправить эту проблему на виртуальной машине, т. е. невозможность доступа к элементу хеш-таблицы? Кроме того, можете ли вы написать ответ на этот вопрос, чтобы я мог дать вам награду.   -  person Sheraram_Prajapat    schedule 21.06.2021
comment
Это похоже на проблему с конфигурацией виртуальной машины, у меня она работает нормально!   -  person Transformer    schedule 21.06.2021


Ответы (1)


Я пошел дальше и запустил весь сценарий как есть до того места, где у вас возникли проблемы с $network_info.AdapterIndex на машине с 64-разрядной версией Windows 7, и я могу без проблем вытащить $AdapterIndex, так что это может быть просто та виртуальная машина. ?

Я бы также рекомендовал передать $AdapterIndex в качестве параметра другим вашим функциям, вместо того, чтобы использовать его как глобальную переменную.

Что касается проблемы невозможности доступа к элементу хеш-таблицы, я считаю, что проблема, вероятно, возникла ранее в вашем скрипте. Например, вы на самом деле не проверяете, есть ли у $network_info какие-либо данные. Я предполагаю, что ваш запрос WMI на этой виртуальной машине на самом деле не возвращает допустимый объект. Попробуйте что-то подобное на 64-битной виртуальной машине win7 — просто удалите некоторые из function структур и -erroraction SilentlyContinue флагов:

$MyMacAddress = "00:00:00:3C:7A:00" # yours here
$MatchingAdapter = Get-WmiObject Win32_NetworkAdapterConfiguration | 
  Where {$_.IPEnabled -and ($_.MACAddress -eq $MyMacAddress )}

# double-check you actually found an adapter via MAC
if (!$MatchingAdapter) {throw "No adapter found with MAC address $MyMacAddress";break}

$AdapterInfo = @{
  AdapterName = (
      Get-WmiObject -Query "SELECT netconnectionID FROM win32_networkadapter WHERE Name = '$($MatchingAdapter.Description)'"
    ).netconnectionid
  AdapterInterfaceDescription = $MatchingAdapter.Description
  AdapterInterfaceIndex = $MatchingAdapter.InterfaceIndex
  AdapterIndex = $MatchingAdapter.Index
}

[PSCustomObject]$AdapterInfo | fl

Если это возвращает разумные значения, то это тоже должно работать:

$Adapter = Get-WMIObject -Query "SELECT * FROM win32_networkadapterconfiguration WHERE index = '$($MatchingAdapter.Index)'"
$IPandSubnetMaskResult = $adapter.EnableStatic($IPAddress, $SubNetMask)
person Cpt.Whale    schedule 22.06.2021