Сценарий PowerShell, работающий как служба, ведет себя странно - PullRequest
2 голосов
/ 11 февраля 2010

Сценарий PowerShell, работающий как служба, ведет себя странно

Проект: Создайте фоновый процесс, который определяет, подключена ли встроенная сетевая карта. Если он подключен, отключите беспроводную сетевую карту. Если встроенная сетевая карта не подключена, повторно включите беспроводную карту.

Почему: Пользователи постоянно загружаются, получая прикольные таблицы маршрутизации ИЛИ привязываясь к неправильным DNS-серверам. Когда они пытаются получить доступ к локальному ресурсу, скажем, к принтерам, они не могут, а затем попадают в мой куб (они подали бы заявку, но это тоже был бы локальный ресурс). Попытка убедить пользователей отключить собственную беспроводную связь (через коммутатор на ноутбуке) или не горячую док-станцию ​​имела ограниченный успех.

Проблема: Сценарий PowerShell, приведенный ниже, работает и работает в моих условиях тестирования. Вероятно, в большинстве условий тестирования, поскольку код и запросы wmi довольно общие. Выполнение сценария вручную дает ожидаемые результаты, ОДНАКО выполнение сценария как службы с помощью единственного метода, который я смог найти, srvany.exe, дает неожиданные результаты и «разбивает вещи».

Подробнее: Запуск сценария как службы через srvany.exe работает ОДИН РАЗ. Когда цикл возвращается, чтобы проверить сетевое соединение или пытается метод включить или отключить его. Ошибки указывают на то, что «get-wmiobject» не является правильным Cmdlet. А? Он работает, вручную, работает один раз, но второй раз после отключения беспроводной сетевой карты - нет. Хуже того, МОЯ оболочка, находящаяся вне службы, внезапно не может выполнить объект get-wmi, пока ... пока вы не зайдете в Диспетчер устройств и не включите беспроводную сетевую карту самостоятельно.

Попытки отладки: Я переписал сценарий и немного его очистил, чтобы он мог выводить объекты за пределы цикла «Пока». Ничего не изменилось, но я оставил сценарий таким, каким он все равно кажется чище. Я включил «Взаимодействие с рабочим столом» в свойствах сервиса и, конечно же, вы можете видеть, что скрипт пытается работать и получает ранее упомянутые ошибки. Пожалуйста помоги. Опять же, цель здесь состоит в том, чтобы запустить фоновый процесс, один из которых имеет достаточно прав в 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")

Ответы [ 2 ]

1 голос
/ 12 февраля 2010

Попробуйте удалить любой вывод. Служба не имеет потока stdout. И когда буфер заполнен, происходит странная вещь. Просто предположение (я никогда не использовал powershell).

0 голосов
/ 09 апреля 2013

Попытки отладки: я переписал скрипт и немного его почистил, чтобы позволяют ему выводить объекты за пределы цикла Do While.

Вам необходимо включить их в цикл, иначе вы не получите обновленные значения, и цикл ничего не сделает.

...