Powershell 脚本更改在 32 位系统上工作但在 64 位系统上不工作的 DNS 属性

Powershell script Changing DNS properties working on 32 bit system but not working on 64 bit

这是更改 DNS 属性配置的脚本,例如设置 IP 地址、默认网关和 DNS 服务器地址,可以在控制面板 -> 网络和共享中心 -> select 适配器中找到-> 属性 -> Internet 协议版本 4(TCP/IPv4).

此脚本 运行 在 windows 7 32-bitwindows 10 32-bit 系统上完美运行,但由于某些原因,它无法在 windows 7 64 bit 上运行。每当我尝试更改 IP 地址时,它都会抛出 error code 97Interface not configurable。如果我直接在 PowerShell 命令行中使用适配器上的功能,例如 $adapter = (get-wmiobject win32_networkadapterconfiguration | where-object {$_.index -eq 7}) $adapter.EnableStatic("192.168.1.50", "255.255.255.0") 它在 Powershell 命令行用户界面上工作。我不明白这是为什么或怎么发生的?

更新:

我尝试调试代码,但发现由于某种原因我无法从 hash_Table network_info 中获取 AdapterIndex,例如

$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


我确实继续 运行 整个脚本,直到您在机器 $network_info.AdapterIndex 遇到问题 运行ning Windows 7 64 -位,而且我能够毫无问题地拉出 $AdapterIndex,所以它可能只是那个 VM?

我还建议将 $AdapterIndex 作为参数提供给您的其他函数,而不是基本上将其用作全局变量。

关于无法访问散列表元素的问题,我相信问题可能出在您的脚本中。例如,您并没有真正检查 $network_info 是否有任何数据。我的猜测可能是您对该 VM 的 WMI 查询实际上 return 不是有效对象。在 64 位 win7 VM 上尝试类似的操作 - 基本上只是删除一些 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

如果 return 的值合理,那么这也应该有效:

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