【问题标题】:PowerShell Script Running as a Service Behaves Strangely作为服务运行的 PowerShell 脚本行为异常
【发布时间】:2010-02-11 20:48:29
【问题描述】:

作为服务运行的 PowerShell 脚本行为异常

项目: 创建一个确定板载网卡是否已连接的后台进程。如果已连接,请禁用无线网卡。当板载网卡未连接时,重新启用无线网卡。

为什么: 用户一直在热停靠,获取时髦的路由表或绑定到错误的 DNS 服务器。当他们尝试访问本地资源(例如打印机)时,他们无法访问,然后就在我的立方体中(他们会提交票证,但这也是本地资源)。试图说服用户禁用他们自己的无线(通过笔记本电脑上的开关)或不使用热坞,但收效甚微。

问题: 下面的 PowerShell 脚本确实运行,并且在我的测试条件下工作。可能在大多数测试条件下,因为代码和 wmi 查询非常通用。手动运行脚本会产生预期的结果,但是通过我能找到的唯一方法 srvany.exe 将脚本作为服务运行,却产生了意想不到的结果并“破坏了东西”。

详情: 通过 srvany.exe 将脚本作为服务运行一次即可。当循环回来测试网络连接或尝试启用或禁用它的方法时。这些错误表明“get-wmiobject”不是正确的 Cmdlet。嗯?它可以手动工作,它可以工作一次,但在禁用无线网卡后第二次就不行了。更糟糕的是,在服务之外,我的 shell 突然无法执行 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")

【问题讨论】:

    标签: windows powershell windows-services daemon


    【解决方案1】:

    尝试删除任何输出。服务没有标准输出流。当缓冲区已满时会发生奇怪的事情。只是一个猜测(我从未使用过 powershell)。

    【讨论】:

    • 这是一个非常好的观点。现在确实有输出。当禁用或启用的方法发生时,就会有输出。嗯嗯
    • 好吧,虽然这确实有帮助,但它给了我一个去修复并学习如何抑制输出的理由。编辑原始帖子以反映更改。
    【解决方案2】:

    调试尝试:我重写了脚本并对其进行了一些清理以 允许它在 Do While 循环之外获取对象。

    您需要将这些包含在循环中,否则您将无法获得更新的值,并且循环不会执行任何操作。

    【讨论】:

      猜你喜欢
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-01
      • 2018-11-03
      • 2015-06-21
      • 1970-01-01
      相关资源
      最近更新 更多