PowerShell脚本从Mac或Linux客户端从SSH(或winexe)启动时不起作用

我有一个Powershell脚本来备份Windows Server 2008 R2框中的MSSQL。 它将特定的数据库备份到本地磁盘,然后将备份移到networking安装的CIFS卷。 无论我如何调用它,在本地运行时都可以100%正常工作。 我安装了Freesshd(最新),能够使用调度程序(不是Windows任务调度程序)启动脚本。 我不断得到cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help abo ut_signing" 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 。 我通过密码validation以本地pipe理员帐户login。

 ################# # 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 $_ } } 

你似乎有两个不同的问题阻止你做你想在这里 – ExecutionPolicy和SysWOW64文件系统redirect。

绕过执行政策

要跳过执行策略,请在启动PowerShell时这样做:

 PowerShell.exe -ExecutionPolicy Bypass -File .\scriptname.ps1 

绕过文件系统redirect

由于freeSSHd似乎是一个32位应用程序,所以Windows试图通过一些漂亮的技巧(或“垃圾”行为,取决于您的偏见)确保64位机器上没有兼容性问题。 一种方法是通过文件系统redirect器

要禁用文件系统redirect,可以调用Wow64DisableWow64FsRedirection Win32 API函数 ,并且来自该线程的所有后续调用将不再受redirect的影响:

 $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位会话中加载configuration文件中的任何64位模块或pipe理单元

使用WinRM远程调用具有适当的安全上下文的脚本SSH不知道如何委托模拟(也不应该)也使用内置到窗口,也可以调用适当的凭据的调度程序。

Windows是可怕的。 Freesshd似乎成为了用于Windows的SSH守护进程的方式,并且使Powershell能够在SSH上运行,这是我长期以来对电脑的最糟糕的体验。 最后,在同事的build议下,我解决了这个问题:

最初,我将其设置为Windows任务计划程序工作,但没有问题,但是我的老板希望我们从主调度程序调用它,并使用SSH来完成此任务。 在经历了百万次powershell失败之后,我最终通过SSH调用了Windows任务计划程序CLI,以使环境成为本地进程的环境。 ssh -l Administrator windows.server.name 'schtasks /RUN /TN "Backup MSI Stats DB"'完成。