M使用 WMIC 和 netsh 使用 Batch 基於索引重命名網路介面

M使用 WMIC 和 netsh 使用 Batch 基於索引重命名網路介面

我有兩個英特爾網卡,我需要根據它們的索引號重命名,WMIC 很好,因為它似乎總是按數字順序返回索引號,因此我們可以直接獲取輸出,而不需要對結果進行排序或運行任何比較操作。

不幸的是,我遇到了一個障礙,如果在 FOR 循環中我使用 netsh 使用索引標記中的變數來顯示介面訊息,它會傳回「無效索引」。我認為問題在於需要在 FOR /F 中使用反引號來切換到命令處理而不是檔案處理。希望有人能夠指出一個簡單的錯誤或為我正在嘗試做的事情提供一個更清晰的解決方案。程式碼如下:

SET INTERFACENAME=LAN1
FOR /F "skip=1 tokens=1 delims=" %%a in (
    'WMIC path Win32_NetworkAdapter where "Manufacturer='Intel'" get index'
) do (
    call :sub1 %%a
)

:sub1
:: %1 = index
FOR /F "skip=2 tokens=1,2 delims=:" %%b in (
    'netsh interface ip show interface index=%index%'
) do (
    if "%%b"=="User-friendly Name" (
        netsh interface set interface name = "%%c" newname = "%INTERFACENAME%" && set INTERFACENAME=LAN2 && exit /b
    )
)

第一個 FOR 迴圈正確解析並將索引號碼傳遞給子例程,但第二個子例程中的 netsh 指令傳回無效索引。子例程中的其餘程式碼尚未經過測試,因此我不確定 INTERFACENAME 變數是否已正確更新。理想情況下,整個過程將透過兩次將 WMIC 命令的第一個結果重命名為 LAN1 並將 WMIC 命令的第二個結果重命名為 LAN2 來運行。

答案1

我只能使用 WMIC 重寫腳本來查詢適當網路介面的資訊。

腳本透過查詢 WMI 來尋找 ipenabled 狀態設定為 true 的網路介面卡。這會清除所有不是實際乙太網路適配器的介面。然後,我們儲存輸出的第一行(實際乙太網路適配器的最低索引號)並將其傳遞給第二個 WMI 查詢。反過來,它利用索引號來取得 netconnectionid,它是適配器「IE 本地連接 1」的實際配置名稱。然後,我們可以將 netconnectionid 傳遞給 netsh 命令來更改該特定適配器的配置。然後我們透過 exit /b 將控制權傳回第一個 FOR 循環,以拉出下一個索引號並再次重複該過程。

透過在 netsh 命令後添加更多 IF / ELSE 比較,可以將其擴展到兩個以上的 NIC。開頭的 NEWNICNAME 值將是套用於最低索引的名稱。 IF / ELSE 比較後設定的 NEWNICNAME 行將套用於報告的下一個最低索引。超業餘程式碼如下:

set NEWNICNAME=Internet
FOR /F "skip=1 tokens=1 delims=" %%a in (
    'wmic path Win32_NetworkAdapterConfiguration where 'ipenabled^="true"' get index'
    ) do (
    set index=%%a && Call :sub1
)

:sub1
FOR /F "skip=1 tokens=1 delims=" %%b in (
    'wmic path Win32_NetworkAdapter where index^=%index% get NetConnectionId'
) do (
    set OGNICNAME=%%b
)
netsh interface set interface name=%OGNICNAME% newname=%NEWNICNAME%
if %NEWNICNAME%==InternalLAN (
    GOTO EOL
) else (
    set NEWNICNAME=InternalLAN
)
exit /b

然而,這在 XP 上有一個大問題。有關使用 netsh 重新命名網路介面卡的文件明確指定在名稱和 newname 值周圍使用雙引號。但是,如果在 Windows XP 中未從提升的 CMD 提示字元執行/呼叫的批次檔中執行此操作,則會破壞命令並傳回「具有此名稱的介面未在路由器中註冊」。不知何故,這個不帶雙引號的完全相同的命令將毫無問題地更改適配器名稱。那麼問題就變成了,如果 NetConnectionId 回傳帶有空格,您的腳本將會失敗。這種行為在我的實例中實際上是可以接受的,因為我可以將主映像部署到我的佇列中,並將兩個 NIC 重新命名為 LAN1 / LAN2,而不是使用帶有空格的名稱。然後,我在實際金屬上執行部署後基於索引的重新配置。

答案2

如果沒有延遲變數擴展,我無法讓 Sam Martin 的批次腳本運行。

這是一個與此類似的腳本,我用它來將 DNS 伺服器設定為特定位址 快速設定DNS

@echo off
setlocal EnableDelayedExpansion
Pushd "%~dp0"

goto start

:Trim
set Params=%*
for /f "tokens=1*" %%a in ("!Params!") do EndLocal & set %1=%%b
exit /b

:exitProg
echo.
echo Operations were completed successfully for any connected network adapters.
echo.
pause
exit

:start 
echo Looking up connected network adapters...
set NICNAME=""

FOR /F "skip=1 tokens=1 delims=" %%a in (
    'wmic path Win32_NetworkAdapterConfiguration where 'ipenabled^="true"' get index'
    ) do (
    set indexMain=%%a
    set indexMainS=!indexMain!
    set index=!indexMainS: =!
    
    set indexTrim=""
    call :Trim indexTrim !index!
    
    if not "!indexTrim!"=="" (
        REM echo Index is !index!
        Call :sub1
    )
)

goto exitProg

:sub1
FOR /F "skip=1 tokens=1 delims=" %%b in (
    'wmic path Win32_NetworkAdapter where index^=%index% get NetConnectionId'
) do (
    set OGNICNAME=%%b
    set NICNAME=!OGNICNAME!
    set NICNAMETRIM=""
    set containerStr=
    call :Trim NICNAMETRIM !NICNAME!
    if not "!NICNAMETRIM!"=="" (
        REM echo calling findstring
        echo !NICNAMETRIM! | findstr /b /l "VirtualBox">temp.txt
        set /p containerStr=<temp.txt
        del temp.txt
        REM echo containerStr is !containerStr!
        if "!containerStr!" == "" (
            echo. 
            echo Network adapter connected to the internet is named "!NICNAMETRIM!"
            echo Calling QuickSetDNS on "!NICNAMETRIM!"
            QuickSetDNS.exe /SetDNS "{IPv4_ONE_ADDR_HERE},{IPv4_TWO_ADDR_HERE}" "!NICNAMETRIM!"
            QuickSetDNS.exe /SetDNS6 "{IPv6_ONE_ADDR_HERE},{IPv6_TWO_ADDR_HERE}" "!NICNAMETRIM!"
        )
    )
)

相關內容