Удаленные сеансы PowerShell и вопрос о области: кажется, что команды выполняются локально

Вот пример сценария, который пытается создать удаленный сеанс на сервере, а затем использует WMI для получения списка пулов приложений IIS сервера и перечисляет их имена:

    function Test-Remoting
    {
        [CmdletBinding()]
        param
        (    
        )
        begin
        {
            Enter-PSSession TestServer
            $appPools = Get-WmiObject -namespace "root\MicrosoftIISv2" -class "IIsApplicationPool" -Authentication 6
            $appPools | ForEach-Object {
                $appPool = $_;
                $appPool.Name
            }
            Exit-PSSession
        }    
    }

Эта функция содержится в файле под названием «Test-Remoting.ps1». Я открываю PowerShell, компакт-диск в каталоге, содержащем этот файл, добавляю файл в исходный код и вызываю функцию:

PS C:\Users\moskie> . .\Test-Remoting.ps1
PS C:\Users\moskie> Test-Remoting

Но результатом этого скрипта является список пулов приложений на моей локальной машине, а не TestServer.

В качестве альтернативы, если я запускаю следующие строки (идентичные строкам в функции) вручную в командной строке PowerShell, я действительно получаю список пулов приложений на удаленном сервере:

PS C:\Users\moskie> Enter-PSSession TestServer
[TestServer]: PS C:\> $appPools = Get-WmiObject -namespace "root\MicrosoftIISv2" -class "IIsApplicationPool" -Authentication 6
[TestServer]: PS C:\> $appPools | ForEach-Object { $appPool = $_; $appPools.Name }
<a list of the names of the application pools on TestServer>
[TestServer]: PS C:\>

Я думаю, что есть концепция, на которую я не обращаю внимания, в отношении удаленного взаимодействия и области действия PowerShell. Кто-нибудь может помочь объяснить такое поведение?


person Moskie    schedule 03.02.2010    source источник


Ответы (1)


Я считаю, что Enter/Exit-PSSession предназначен для более интерактивного использования. Из справки Enter-PSSession:

SYNOPSIS
    Starts an interactive session with a remote computer.

В скрипте используйте New-PSSession и Invoke-Command следующим образом:

$session = New-PSSession server01
Invoke-Command -Session $session {hostname}
Remove-PSSession -Session $session

Обновление: для удаленного выполнения полного скрипта используйте параметр FilePath в Invoke-Command:

icm server01 -FilePath C:\users\keith\myscript.ps1 -arg 1,2

Это скопирует сценарий на удаленный компьютер server01 и выполнит его там с указанными параметрами.

person Keith Hill    schedule 04.02.2010
comment
Я попробую, но я хотел бы избежать такого обходного пути, потому что сценарий, который я хочу запустить, довольно сложен. Было бы неудобно запускать каждую команду через Invoke-Command. Использование Enter/Exit-PSSession было бы наиболее удобным, потому что мне просто нужно было бы окружить свой скрипт этими командами. - person Moskie; 04.02.2010
comment
Если это скрипт, то вы можете сделать это Invoke-Command -FilePath myscript.ps1, и PowerShell переместит файл на удаленную машину и выполнит его там. - person Keith Hill; 04.02.2010
comment
Спасибо, в итоге я пошел по этому пути, поэтому я отмечу ваш ответ. Но это понятие интерактивного сеанса немного расплывчато... мне кажется логичным, что когда у меня есть сценарий, выполняющий команду для входа в новый сеанс, команды, которые следуют за ним, будут выполняться в этом новом сеансе. Не думаю... еще раз спасибо! - person Moskie; 05.02.2010
comment
Да, похоже, это ломает модель того, что все, что вы вводите в командной строке, может быть вставлено в сценарий и работает. - person Keith Hill; 06.02.2010