我有一个 Powershell 脚本,用于在 Windows Server 2008 R2 机箱上备份 MSSQL。它将特定数据库备份到本地磁盘,然后将备份移动到网络挂载的 CIFS 卷。无论我如何调用它,它在本地运行时都能 100% 正常工作。我安装了 Freesshd(最新版本)以便能够使用调度程序(不是 Windows 任务调度程序)启动脚本。我不断cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help abo ut_signing"
通过 SSH 连接,调用 powershell,然后运行 .\scriptname。运行get-executionpolicy
返回remoteSigned
。我通过密码验证以本地管理员帐户身份登录。
#################
# 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 $_ }
}
答案1
您似乎有两个不同的问题阻止您在此处执行您想做的事情 - ExecutionPolicy 和 SysWOW64 文件系统重定向。
绕过执行策略
要绕过执行策略,请在启动 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
避免在 32 位会话中加载配置文件中的任何 64 位模块或管理单元
答案2
使用 WinRM 远程调用具有适当安全上下文的脚本 SSH 不知道如何委派模拟(也不应该这样做)也使用 Windows 内置的调度程序,它也可以使用适当的凭据进行调用。
答案3
Windows 太糟糕了。Freesshd 似乎是 Windows 上 SSH 守护进程的最佳选择,而让 Powershell 在 SSH 上工作是我很长时间以来使用电脑时遇到的最糟糕的体验。最后,在同事的建议下,我这样解决了这个问题:
最初,我将其设置为 Windows 任务计划程序作业,并且一切正常,但我的老板希望我们从主计划程序调用它,并使用 SSH 来执行此操作。在无数次 powershell 失败之后,我最终通过 SSH 调用 Windows 任务计划程序 CLI,以便环境成为本地进程。 ssh -l Administrator windows.server.name 'schtasks /RUN /TN "Backup MSI Stats DB"'
完成。