2

I have a Powershell script to backup MSSQL on a Windows Server 2008 R2 box. It backs up a specific DB to a local disk, then moves the backup to a Network mounted CIFS volume. It works 100% fine when run locally no matter how I invoke it. I installed Freesshd (latest) to be able to start the script using a scheduler (not windows task scheduler ). I am constantly getting 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. Running get-executionpolicy returns 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 $_ }
}
sed_and_done
  • 183
  • 8

3 Answers3

4

You seem to have two different issues preventing you from doing what you want here - ExecutionPolicy and SysWOW64 File System Redirection.

Bypass Execution Policy

To bypass the execution policy, do so when launching PowerShell, like so:

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

Bypass File System Redirection

Since freeSSHd seems to be a 32-bit application, Windows tries to ensure no compatibility issue on your 64-bit machine, by way of a few nifty tricks (or "garbage" behavior, depending on your preconception). One way is via the File System Redirector

To disable File System Redirection, you can call the Wow64DisableWow64FsRedirection Win32 API function, and all subsequent calls from that thread will no longer be affected by redirection:

$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

Save the above as a script (wrapper.ps1), and invoke it from ssh with:

powershell -ExecutionPolicy Bypass -NoProfile -File .\wrapper.ps1

To avoid any 64-bit modules or snapins from the profile being loaded in the 32-bit session

Mathias R. Jessen
  • 24,907
  • 4
  • 62
  • 95
  • I tried that, it doesn't work. – sed_and_done Mar 26 '15 at 17:55
  • What error message do you get? – Mathias R. Jessen Mar 26 '15 at 17:56
  • I think there is some fundamental buggyness with this combination, I am actually getting past the execution policy error, but it is finding no snap-ins. I thought maybe the Powershell in my Path was different with whatever environment SSH is using (seems weird), so I used the full path to Powershell, but it says `"Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 1."` Sorry for just saying "it didn't work" I had tried the command you supplied earlier and didn't notice I was getting a different error. – sed_and_done Mar 26 '15 at 17:59
  • Try with the full path to the powershell executable: `C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe` – Mathias R. Jessen Mar 26 '15 at 18:13
  • I mentioned I did that in the comment above, it's a good idea, but it didn't fix the issue. – sed_and_done Mar 26 '15 at 19:37
  • ls env:\processor_architecture is x86 from SSH session, but AMD64 local. Windows is garbage. – sed_and_done Mar 26 '15 at 20:40
  • No, Windows is equipped with a sometimes overly helpful [File System Redirector](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx) – Mathias R. Jessen Mar 26 '15 at 20:45
  • Impressive. Let me read over it and see when I have time to really try this. You are definitely knowledgeable about Windows, I appreciate your time and effort. Powershell is such a strange language, it's not quite a proper shell, and not quite like a high level language. It kind of makes me think of a Perl shell, but with a lot of esoteric dot-net underpinnings. – sed_and_done Mar 26 '15 at 21:50
0

Use WinRM to invoke the script with the proper security context remotely SSH doesn't know how to delegate impersonation (nor should it) also use the scheduler built in to windows which can also invoke with the proper credentials.

Jim B
  • 23,938
  • 4
  • 35
  • 58
0

Windows is horrific. Freesshd seems to be the way to go for an SSH Daemon for Windows, and to get Powershell to work at all over SSH was the worst experience I have had with computers in a long time. In the end, with a suggestion from my coworker, this is how I solved it:

Initially, I set this up as a Windows Task Scheduler job, and it was fine, but my boss wanted us to call it from our main scheduler, and use SSH to do so. After a Million powershell failures, I ended up calling the Windows task scheduler CLI via SSH so that the environment was that of a local process. ssh -l Administrator windows.server.name 'schtasks /RUN /TN "Backup MSI Stats DB"' Done.

sed_and_done
  • 183
  • 8