none
Powershell event forwarding

    Вопрос

  • Для начала с Новым Годом! Я подозреваю что не я первый тут к Вам с вопросами :) Но уже просто всю голову сломал!

    Проблема вот в чем. Я хочу подписаться на некие события с удаленной машины при помощи powershell event forwarding. Однако - что-то не выходит. Если локально - все работает. А вот сам форвардинг ...:

    вот код:

    $remoteComputer = "."
    $session = New-PsSession $remoteComputer
    
    Unregister-Event CatchEvent -ErrorAction SilentlyContinue
    Invoke-Command $session {
        ## The WMI query to detect a stopping service
        $query = @"
            SELECT *
            FROM __instancecreationevent
            WHERE TargetInstance ISA 'Win32_NtLogEvent'
            and targetinstance.eventcode = '7036'
    "@
        Register-WmiEvent -Query $query "CatchEvent" -Forward
    }
    
    $null = Register-EngineEvent CatchEvent -Action { $GLOBAL:MyEvent = $event}
    

     

    В конечном итоге в $MyEvent нет нигде данных о событии. В $MyEvent.SourceEventArgs.SerializedRemoteEventArgs.NewEvent.TargetInstance лежит строка System.Management.ManagementBaseObject, да и сам он System.String соответственно. Как достать до события - ума не приложу.
    6 января 2010 г. 5:52

Ответы

  • Если вы хотите чтобы на вашем компьютере выполнился код при остановке сервиса на другом компьютере, то для этого не нужны Remoting и -forward:
    $query = "SELECT * FROM __instancecreationevent WHERE TargetInstance ISA 'Win32_NtLogEvent' AND TargetInstance.eventcode = '7036'"
    Register-WmiEvent -Query $query -ComputerName client1 -Action {write-host "Service Stopped"}

    Если делать это с помощью ремотинга, как в вашем примере, то возникнет следующая проблема: Remoting не может передавать "живые" объекты любых классов (а в PS они могут быть любыми) по сети, и поэтому для передачи они сериализуются, а на компьютере получателе собираются заново. Разумеется при этом теряются любые методы объектов, свойства обрезаются до определенного уровня вложенности, а нестандартные классы, которые нельзя передать в виде базовых классов (строка, число, и т.п.) преобразовываются в строки. Именно это и случилось с $Event. Если вы воспользуетесь моим вариантом, то будет использован "WMI Remoting" и данные будут переданы средствами WMI (которые умеют передавать только объекты WMI, но зато полностью :) ).
    Вывод: PS Remoting хорош своей универсальностью, но в данном случае эффективнее будет воспользоваться родными возможностями WMI.


    AKA Xaegr, MCSE: Security, Messaging; MCITP: Server\Enterprise Administrator; Блог: http://xaegr.wordpress.com
    • Предложено в качестве ответа Vasily GusevModerator 6 января 2010 г. 7:47
    • Помечено в качестве ответа Eosfor 6 января 2010 г. 13:09
    6 января 2010 г. 7:47
    Модератор

Все ответы

  • Если вы хотите чтобы на вашем компьютере выполнился код при остановке сервиса на другом компьютере, то для этого не нужны Remoting и -forward:
    $query = "SELECT * FROM __instancecreationevent WHERE TargetInstance ISA 'Win32_NtLogEvent' AND TargetInstance.eventcode = '7036'"
    Register-WmiEvent -Query $query -ComputerName client1 -Action {write-host "Service Stopped"}

    Если делать это с помощью ремотинга, как в вашем примере, то возникнет следующая проблема: Remoting не может передавать "живые" объекты любых классов (а в PS они могут быть любыми) по сети, и поэтому для передачи они сериализуются, а на компьютере получателе собираются заново. Разумеется при этом теряются любые методы объектов, свойства обрезаются до определенного уровня вложенности, а нестандартные классы, которые нельзя передать в виде базовых классов (строка, число, и т.п.) преобразовываются в строки. Именно это и случилось с $Event. Если вы воспользуетесь моим вариантом, то будет использован "WMI Remoting" и данные будут переданы средствами WMI (которые умеют передавать только объекты WMI, но зато полностью :) ).
    Вывод: PS Remoting хорош своей универсальностью, но в данном случае эффективнее будет воспользоваться родными возможностями WMI.


    AKA Xaegr, MCSE: Security, Messaging; MCITP: Server\Enterprise Administrator; Блог: http://xaegr.wordpress.com
    • Предложено в качестве ответа Vasily GusevModerator 6 января 2010 г. 7:47
    • Помечено в качестве ответа Eosfor 6 января 2010 г. 13:09
    6 января 2010 г. 7:47
    Модератор
  • А раз так, то для чего стоит использовать ремотинг? Как то ограничьте область применения чтоли. Чтобы хоть не пытаться разбить головой стену в будущем.
    6 января 2010 г. 13:11
  • Для чего ремоутинг? Для выполнения скрипта на удаленной системе :-) Если вопрос про ремоутинг в связке с WMI, то в рамках домена и локальной сети WMI прекрасно работает и нет нужды использовать посредников, но если вам надо дотянуться до удаленной машины, которая не в домене, и тем более по незашищенной сети, то средства Powershell Remoting вас спасут от нагромождения vpn-нов, ipsec-ов, продуктов третьих фирм и т.п.
    Сазонов Илья http://www.itcommunity.ru/blogs/sie-wl/
    8 января 2010 г. 11:56
    Модератор