Powershell Invoke-Command не запускается на удаленном компьютере. Не выводится сообщение об ошибке значения [дубликат]

Краткий ответ: ваш метод foo() возвращается немедленно, а вызов $ajax() выполняется асинхронно после возврата функции . Проблема заключается в том, как и где сохранить результаты, полученные при вызове async, после его возврата.

В этом потоке было задано несколько решений. Возможно, самый простой способ - передать объект методу foo() и сохранить результаты в члене этого объекта после завершения асинхронного вызова.

function foo(result) {
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;   // Store the async result
        }
    });
}

var result = { response: null };   // Object to hold the async result
foo(result);                       // Returns before the async completes

Обратите внимание, что вызов foo() ] все равно не вернут ничего полезного. Однако результат асинхронного вызова теперь будет сохранен в result.response.

3
задан SKJ 31 October 2014 в 16:15
поделиться

3 ответа

Это звучит как проблема с двойной аутентификацией. После того как вы удалены на сервер, вы не можете получить доступ к файловому ресурсу на третьем сервере, потому что вы не можете передать ему аутентификацию на основе кебероса.

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

Вы могли бы настроить CredSSP , что не является большой идеей для этой цели.

В основном вам нужно избегать подключения к одной машине, а затем подключиться к другому через это соединение.

Код, который реализует Обходной путь, который я описываю:

param(
[String] $ServerNameFilePath = $(throw "Provide the path of text file which contains the server names"),
[String] $InstallerFolderPath = $(throw "Provide the Installer Folder Path. This should be a network location"),
[String] $UserName = $(throw "Provide the User Name"),
[String] $Password= $(throw "Provide the Password")
)
Function InstallApp
{
    $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
    $mycreds = New-Object System.Management.Automation.PSCredential ($UserName, $secpasswd)


    $ScrBlock = {param($InstallerFolderPath) $ExePath = Join-Path $InstallerFolderPath "ServerReleaseManager.exe";  & $ExePath /q;}

    Get-Content Servers.txt | ForEach-Item {
        $remoteDest = "\\$_\c`$\some\temp\folder"
        $localDest = "C:\some\temp\folder" | Join-Path -ChildPath ($InstallerFolderPath | Split-Path -Leaf)

        try {
            Copy-Item -Path $InstallerFolderPath -Destination $dest -Force
            Invoke-Command -ComputerName $_ -Credential $mycreds $ScrBlock -ArgumentList $localDest
        finally {
            Remove-Item $remoteDest -Force -ErrorAction Ignore
        }
    }
}

InstallApp -ServerNameFilePath $ServerNameFilePath -InstallerFolderPath $InstallerFolderPath -UserName $UserName -Password $Password

Примечания

  1. Это не проверено.
  2. Как упоминалось Swonkie, вы должны установить свои параметры как обязательные если это то, что вы хотите достичь (не рассматривается в моем коде).
  3. Вам не следует передавать отдельные параметры имени пользователя и пароля для обычного текста, а затем преобразовывать их в объект учетных данных. Вместо этого передайте один параметр [PSCredential]. Вы можете использовать значение по умолчанию, которое запрашивает, например [PSCredential] $Cred = (Get-Credential). (это также не рассматривается в моем коде).
2
ответ дан Community 26 August 2018 в 22:15
поделиться

Здесь я создал новый PSsession для каждого сервера в списке и использовал команду invoke для таргетинга на этот сервер. Я протестировал его в своей среде, и он успешно устанавливает мое приложение exe с помощью ключа / q на моих удаленных серверах.

Этот метод, однако, не указывает, успешно ли вы выполнили команду на удаленной стороне, вам нужно будет выполнить вход на сервер или выполнить тестовый путь к ожидаемому местоположению установленных файлов для проверки. Кроме того, PSsessions остаются открытыми до тех пор, пока консоль, запускающая команду, не будет закрыта. Если PSsession заканчивается до завершения установки, установка завершится с ошибкой.

Function InstallApp {

    param(
        [parameter(Mandatory=$true)] [String] $ServerNameFilePath,
        [parameter(Mandatory=$true)] [String] $InstallerFilePath,
        [parameter(Mandatory=$true)] [String] $CommandArgument,
        [parameter(Mandatory=$true)] [String] $UserName,
        [parameter(Mandatory=$true)] [String] $Password
    )

    $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
    $mycreds = New-Object System.Management.Automation.PSCredential ($UserName, $secpasswd)

    Get-Content $ServerNameFilePath | ForEach-Object {
        $remoteSession = new-PSSession $_ -Credential $mycreds
        Invoke-command -Session $remoteSession -Scriptblock {& ($args[0]) @($args[1])} -ArgumentList $InstallerFilePath,$CommandArgument 
    }
}

InstallApp -ServerNameFilePath $ServerNameFilePath -InstallerFilePath $InstallerFilePath -CommandArgument $CommandArgument -UserName $UserName -Password $Password
3
ответ дан Dino Padilla 26 August 2018 в 22:15
поделиться

Конфигурация желаемого состояния может быть использована для установки программного обеспечения на целевые компьютеры. Я предполагаю, что это может обойти проблему двойного перескока.

http://technet.microsoft.com/de-de/library/dn282132.aspx

http://technet.microsoft.com/de-de/library/dn282129.aspx

Кстати, не допускайте ошибок при отсутствии обязательных аргументов. Пусть PowerShell справится с этим - он гораздо удобнее:

param(
    [parameter(Mandatory=$true)] [string] $ServerNameFilePath,
    [parameter(Mandatory=$true)] [string] $InstallerFolderPath,
    [parameter(Mandatory=$true)] [string] $UserName,
    [parameter(Mandatory=$true)] [string] $Password
)
3
ответ дан Swonkie 26 August 2018 в 22:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: