作为服务运行的PowerShell脚本行为奇怪
项目: 创建后台进程,确定是否已连接板载网卡。如果已连接,请禁用无线网卡。未连接板载网卡时,请重新启用无线网卡。
为什么: 用户始终热插拔,获得时髦的路由表或绑定到错误的DNS服务器。当他们试图访问本地资源时,比如打印机,他们无法进入我的立方体(他们会提交票证,但这也是本地资源)。试图说服用户禁用他们自己的无线(通过笔记本电脑上的开关)或不热的码头已经取得了有限的成功。
问题: 下面的PowerShell脚本确实运行,并且在我的测试条件下工作。可能在大多数测试条件下,因为代码和wmi查询非常通用。手动运行脚本会产生预期的结果,但是通过我能找到的唯一方法运行脚本作为服务,srvany.exe,产生了意想不到的结果并“破坏了东西”。
详细说明: 通过srvany.exe将脚本作为服务运行,可以使用ONCE。当循环返回以测试网络连接或尝试该方法启用或禁用它时。错误表明“get-wmiobject”不是一个合适的Cmdlet。咦?它工作,手动,它工作一次,但第二次禁用无线网卡后,它没有。更糟糕的是,我的外壳,在服务之外,突然不能做一个获取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")
答案 0 :(得分:1)
尝试删除任何输出。服务没有标准输出流。当缓冲区满了奇怪的事情发生。只是一个猜测(我从未使用过powershell)。
答案 1 :(得分:0)
调试尝试:我重写了脚本并将其清理干净了一点 允许它获取Do While循环之外的对象。
您需要在循环中包含这些内容,否则您将无法获得更新的值,循环将不执行任何操作。