Скрипт Powershell не работает при запуске из SSH (или winexe) с клиента Mac или Linux
У меня есть сценарий Powershell для резервного копирования MSSQL на коробке Windows Server 2008 R2. Резервное копирование определенной БД на локальный диск, а затем перемещает резервную копию на том CIFS, смонтированный в сети. Он работает на 100% нормально, когда запускается локально, независимо от того, как я его вызываю. Я установил Freesshd (последний), чтобы иметь возможность запускать скрипт с помощью планировщика (не планировщика задач Windows). Я постоянно получаю cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help abo
ut_signing"
I connect via SSH, invoke powershell, then run .\scriptname. Бег get-executionpolicy
возвращается remoteSigned
, I am logged in as the local Administrator account via password authentication.
#################
# Backup MSI #
# A POwershell #
# Script. #
#################
#load SQL snap-in
Add-PSSnapin *SQL*
#pull the current date
$date = Get-Date -Format yyyyddMM
#set location of backup files and create it if not present
$DIRECTORY = "D:\Temp\"
if (-Not (Test-Path $DIRECTORY) ) { md $directory }
#Grab the database names into an array
$dbname = dir 'SQLSERVER:\SQL\MYHOST\MYDBMSSQL\Databases' | Select Name
#Backup each database found which matches the regex "stats".
$dbname | foreach { $_.Name.ToString() }|where { $_ -match "stats" } | foreach {$bakfile = "$DIRECTORY" + $_ + "_" + $date + ".bak";
"Backing up Database: $_"; Invoke-Sqlcmd -QueryTimeout 10000 -SuppressProviderContextWarning -Query "BACKUP DATABASE $_ TO DISK=N'$bakfile' WITH INIT";}
# Move Backup from local disk to CIFS mount
Copy-Item $DIRECTORY\*.bak \\e-nfs-01.mycompany.net\backup-bi-em\Backups
Remove-Item $DIRECTORY\*.bak
cd \\e-nfs-01.mycompany.net\backup-bi-em\Backups
#Get array of existing Backups
$backups=@( ls \\e-nfs-01.mycompany.net\backup-bi-em\backups\*.bak|sort-object -property CreationTime -descending|foreach { $_.Name } )
#Delete Anything Beyond 3 Newest Backups
if ($backups.Length -gt 3 ) {
foreach ($_ in $backups[3..$backups.Length]) { Remove-Item $_ }
}
3 ответа
Похоже, у вас есть две разные проблемы, мешающие вам делать то, что вы хотите, здесь - ExecutionPolicy и SysWOW64 Redirection File System.
Обойти политику выполнения
Чтобы обойти политику выполнения, сделайте это при запуске PowerShell, например так:
PowerShell.exe -ExecutionPolicy Bypass -File .\scriptname.ps1
Обход перенаправления файловой системы
Так как freeSSHd кажется 32-битным приложением, Windows старается не допустить проблем совместимости на вашей 64-битной машине с помощью нескольких хитрых приемов (или "мусорного" поведения, в зависимости от вашего предубеждения). Один путь через перенаправитель файловой системы
Чтобы отключить перенаправление файловой системы, вы можете вызвать Wow64DisableWow64FsRedirection
Функция Win32 API, и все последующие вызовы из этого потока больше не будут затронуты перенаправлением:
$MethodSignature = @"
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
"@
$Kernel32 = Add-Type -MemberDefinition $MethodSignature -Namespace "Kernel32" -Passthru
$ptr = [IntPtr]::Zero
$Result = $Kernel32::Wow64DisableWow64FsRedirection([ref]$ptr)
# Now you can call 64-bit Powershell from system32
C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File .\Script.ps1
Сохраните вышеперечисленное как скрипт (wrapper.ps1
) и вызвать его из ssh с помощью:
powershell -ExecutionPolicy Bypass -NoProfile -File .\wrapper.ps1
Чтобы избежать каких-либо 64-битных модулей или оснасток из профиля, загружаемых в 32-битном сеансе
Используйте WinRM для удаленного вызова сценария с правильным контекстом безопасности. SSH не знает, как делегировать олицетворение (и не должно), также использует встроенный в окна планировщик, который также может вызывать с соответствующими учетными данными.
Windows ужасна. Похоже, что Freesshd - это способ использовать SSH Daemon для Windows, и заставить Powershell работать над SSH было худшим опытом, с которым я столкнулся на компьютерах за долгое время. В конце концов, по предложению моего коллеги, я решил это так:
Первоначально я настроил это как задание Windows Task Scheduler, и это было нормально, но мой начальник хотел, чтобы мы вызывали его из нашего основного планировщика и использовали для этого SSH. После миллиона сбоев PowerShell я в конечном итоге вызвал CLI планировщика задач Windows через SSH, чтобы среда представляла собой локальный процесс. ssh -l Administrator windows.server.name 'schtasks /RUN /TN "Backup MSI Stats DB"'
Готово.