Какие способы существуют для повышения скорости выполнения PowerShell скрипта?

У меня есть следующий скрипт: 
<pre><code>$username = 'keksxj'
$password = 'пароль'
$secpw = ConvertTo-SecureString $password -AsPlainText -Force
$cred  = New-Object Management.Automation.PSCredential ($username, $secpw)
Invoke-Command -VMName 'app' -Credential $cred  {C:\Users\keksxj\Desktop\way\mainzapusk.ps1}</code></pre> 
С его помощью я запускаю другой скрипт на "удалённом ПК", который инициирует приложение. Однако я недоволен скоростью выполнения, так как оно занимает около 5 секунд, что для моей задачи слишком долго. 

Я пытался оптимизировать этот процесс, разделив скрипт на два отдельных файла: 
Первый скрипт: 
<pre><code>$username = 'keksxj'
$password = 'пароль'
$secpw = ConvertTo-SecureString $password -AsPlainText -Force
$cred  = New-Object Management.Automation.PSCredential ($username, $secpw)
$s = New-PSSession -VMName 'app' -Credential $cred</code></pre> 
Второй скрипт: 
<pre><code>Invoke-Command  -Session $s  {C:\Users\keksxj\Desktop\way\mainzapusk.ps1}</code></pre> 

Однако, как я понял, нельзя разделять скрипт таким образом, поскольку сессия PSSession не сохраняется при запуске из другого скрипта (поправьте меня, если я ошибаюсь). 

Мой вопрос заключается в том, возможно ли ускорить выполнение этого скрипта? Например, можно ли каким-то образом обойти часть, связанную с авторизацией, чтобы данные запоминались раз и навсегда?
  • 31 октября 2024 г. 11:53
Ответы на вопрос 2
Чтобы повысить скорость выполнения вашего PowerShell скрипта, можно рассмотреть несколько подходов и оптимизаций:

### 1. Использование `PSSession`

Как вы правильно заметили, при запуске из разных скриптов сессия `PSSession` не сохраняется. Чтобы избежать многократной авторизации и ускорить выполнение разнесите создание сессии и выполнение команд на одной машине:

```powershell
# Скрипт 1: Создание сессии и сохранение в переменной
$username = 'keksxj'
$password = 'пароль'
$secpw = ConvertTo-SecureString $password -AsPlainText -Force
$cred  = New-Object Management.Automation.PSCredential ($username, $secpw)

$s = New-PSSession -VMName 'app' -Credential $cred
# Сохраняем сессию в файл, чтобы использовать повторно
$s | Export-Clixml -Path "C:\path\to\session.xml"

# Убедитесь, что в конце работы вы закрываете сессию
# Remove-PSSession $s
```

```powershell
# Скрипт 2: Использование сохраненной сессии
$s = Import-Clixml -Path "C:\path\to\session.xml"
Invoke-Command -Session $s {C:\Users\keksxj\Desktop\way\mainzapusk.ps1}
```

### 2. Избегайте частого создания сессий

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

### 3. Используйте `-NoNewWindow` для запуска GUI приложений

Если `mainzapusk.ps1` запускает GUI приложение, проверьте, можно ли его запустить в фоновом режиме без создания нового окна или интерфейса, используя опцию `-NoNewWindow`.

### 4. Оптимизация самого скрипта `mainzapusk.ps1`

Посмотрите, нет ли в `mainzapusk.ps1` мест, где можно оптимизировать выполнение (удаление лишних вызовов, оптимизация кода и т.д.).

### 5. Используйте Task Scheduler

Если нужно запускать скрипт по расписанию, может быть проще настроить его выполнение через Task Scheduler, а затем вызывать этот таск из PowerShell, избегая посвящения кода в самом удаленном экземпляре.

### 6. Храните креденшалы безопасно

Вы также можете использовать `Get-Credential` для безопасного хранения учётных данных и использовать их при дальнейшем обращении к удаленной машине:

```powershell
$cred = Get-Credential
```

### 7. Сетевые проблемы

Если удаленный хост медленно отвечает, вы также можете столкнуться с проблемами на уровне сети. Убедитесь, что скорость сети и её стабильность достаточно высока.

### Заключение

Не существует единственного решения для всех сценариев, поэтому стоит поэкспериментировать с различными подходами и протестировать результаты. Возможно, сочетание нескольких методов приведет к значительному улучшению производительности.
Kekxx , ну, не WMI,  а WinRM. 
PowerShell Direct для того, чтобы администрировать виртуальные машины. Использовать его как замену удалённого доступа на стенде или в домашних условиях, конечно, можно. Но причина "по другому не работает" тут, скорее, индикатор, что инструмент выбран неверно.

Если просто забить в Google ту строку, что возвращает PsExec, то уже на странице поиска будет понятно, что там написано.

А если сопоставить этот вопрос и прошлый(-лые), то создаётся впечатление, что это попытка наваять что-то мутное на коленке.
______________________________
Что касается вопроса - одновременный запуск проще будет сделать используя планировщик или ожидание нужного времени в самом скрипте
(разумеется, надо убедиться в синхронизации времени между узла и).
______________________________
Что касается проблемы доступа к ВМ, предположу, что это ПК и виртуальная машина не входят в домен, то есть, используют [разные] локальные учётные записи, а ошибки вызванв попытками использовать учётную запись одного узла в качестве учётной записи для другого узла.
Похожие вопросы