2010-02-11 83 views
2

PowerShell腳本運行作爲服務行爲異常PowerShell腳本運行作爲服務行爲異常

項目: 創建一個後臺進程確定是否在船上網絡卡被連接。如果已連接,請禁用無線網卡。當板載網卡未連接時,重新啓用無線網卡。

爲什麼: 用戶一直熱插拔,越來越時髦的路由表或綁定到錯誤的DNS服務器。當他們嘗試訪問本地資源時,比方說打印機,他們無法訪問我的多維數據集(他們會提交票據,但這也是本地資源)。試圖說服用戶禁用他們自己的無線(通過筆記本電腦上的開關)或不熱碼頭已經取得了有限的成功。

問題: 下面的PowerShell腳本確實運行,並且在我的測試條件下工作。可能在大多數測試條件下,因爲代碼和wmi查詢非常通用。手動運行腳本會產生預期的結果,但是通過我能找到的唯一方法srvany.exe運行腳本作爲服務,產生了意想不到的結果和「破壞的東西」。

詳細信息: 通過srvany.exe運行腳本作爲服務運行ONCE。當循環回來測試網絡連接或嘗試使用該方法啓用或禁用它時。錯誤表明「get-wmiobject」不是合適的Cmdlet。咦?它工作,手動,它只工作一次,但第二次後,它禁用無線網卡它不。更糟糕的是,除了服務外,我的外殼突然不能做一個get-wmiobject,直到......。直到您進入設備管理器並自行重新啓用無線網卡。

調試嘗試: 我重寫了腳本並稍微清理了一下,以便它可以獲取Do While循環之外的對象。沒有什麼改變,但我以這種方式離開了腳本,因爲它似乎更清潔。我在服務屬性中啓用了「與桌面交互」,並確保您可以看到腳本嘗試工作並獲取之前提到的錯誤。 請幫忙。這裏的對象再次運行後臺進程,在Vista或7中具有足夠的權限來禁用和啓用無線網卡。

#*********************************************************************** 
# "switch-wifi-srv.ps1" 
# This script attempts to identify if a wired network card is in use if 
# one is, the Wireless network card is disabled, until the wired network 
# card is no longer in use. 
# 
# Written by Aaron Wurthmann - aaron (AT) wurthmann (DOT) com 
# 
# 2010.02.10 ver 2 (Service Version) 
# If you edit please keep my name or at the very least original author's. 
# As of this writing I am unsure if script will work with all scenarios, 
# however it has worked for me on Dell laptops running Windows 7 x64. 
# ----------------------------------------------------------------------- 
# This script comes with ABSOLUTELY NO WARRANTY. 
# You may redistribute copies of the script under 
# the terms of the GNU General Public License. 
# ----------------------------------------------------------------------- 
# Service Installation: 
# Aquire and install the Windows 2003 Resource Kit OR the srvany.exe. 
# Use sc.exe and srvany.exe to create a service.... 
# sc create SwitchWifiAuto binPath= "C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe" DisplayName= "Switch Wifi Automatically" 
# Edit registry entry for SwitchWifiAuto, add a key and a string value... 
# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SwitchWifiAuto\Parameters] 
# "Application"="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy RemoteSigned -File C:\\SwitchWifiAuto\\switch-wifi-srv.ps1" 
#************************************************************************ 


$state="" 
$wireStatus="" 
$wifiStatus="" 

# Get Wired and Wireless Card Objects 
$objWire=get-wmiobject -class win32_networkadapter -namespace root\CIMV2 | Where-Object {$_.Name -notmatch "Wireless" -and $_.Name -notmatch "Virtual" -and $_.PhysicalAdapter -eq "True"} 
$objWifi=get-wmiobject -class win32_networkadapter -namespace root\CIMV2 | where-object {$_.Name -match "Wireless"} 

# Get Name of Service to be Used in totally useless Do While Loop 
$objService=get-service -display "Switch Wifi Automatically" 

# Begin Do While Loop 
Do { 
# Get status of wired network card. If enabled and connected set $state to Disable (which will later Disable the Wifi network card) 
    [string]$wireStatus=$objWire | % {$_.NetEnabled} 
    if($wireStatus -eq "True") { 
     $state="Disable" 
    } 
# Get Status of wireless card. 
    if($objWifi){ 
     [string]$wifiStatus=$objWifi | % {$_.NetEnabled} 
#  If $state is not set to disable and if the wireless card is currently disabled, enable it. 
     if($state -ne "Disable") { 
      if($wifiStatus -eq "False") { 
       Out-Null -InputOject ($objWifi | % {$_.Enable()}) 
      } 
#  If $state is set to Disable and if wireless card is currently enabled, disable it. 
     } else { 
      if($wifiStatus -eq "True") { 
       Out-Null -InputOject ($objWifi | % {$_.Disable()}) 
      } 
     } 
    } 

# Reset Checked Variables for good measure 
$state="" 
$wireStatus="" 
$wifiStatus="" 

# Sleep for 120 seconds (two minutes) 
Start-Sleep -s 120 

# Continuing looping (do while) until the service is not running. 
# This is of course technically useless as when the service is not running neither is the script to check if the service is not running. 
# I made it this way however because I don't like infinite loops and I thought it would be funny to it this way instead of while $var=0 
} while ($objService.Status -eq "Running") 

回答

1

嘗試刪除任何輸出。服務沒有標準輸出流。而當緩衝區是完全奇怪的事情發生。只是一個猜測(我從來沒有使用PowerShell)。

+0

這是一個非常好的觀點。現在確實有輸出。當禁用或啓用的方法發生時,會輸出。 Hrmmmm – 2010-02-12 00:42:05

+0

那麼這不是它,雖然這有幫助,它給了我一個理由去修復,並學習如何抑制輸出。 編輯原始帖子以反映更改。 – 2010-02-12 17:48:52

0

調試嘗試:我重寫了腳本並將其稍微清理一下,以便 允許它獲取Do While循環之外的對象。

您需要將這些內容包含在循環中,否則您將無法獲取更新值,循環將無法執行任何操作。