Problem executing REMOTE powershell script using WinSCP via SQL Server Agent Job - sql-server

On SQL Server 2016 I have setup a job that executes a powershell script that resides on a remote app server. When I execute the powershell script via the app server using the Powershell ISE app my script works without issue. When I had setup the job and enter this command:
powershell.exe -ExecutionPolicy Bypass -file "\\serverapp1\c$\coverageverifier_scripts\SFTP_CoverageVerifier.ps1" in Step 1.
When I look at the VIEW HISTORY I see the error below but I cannot figure out why the script now cannot load the file or assembly.
Any help/direction would be appreciated. Here is the error:
The job script encountered the following errors. These errors did not stop the script: A job step received an error at line 1 in a PowerShell script. The corresponding line is 'powershell.exe -ExecutionPolicy Bypass -File "\empqaapp1\c$\coverageverifier_scripts\SFTP_CoverageVerifier.ps1"'. Correct the script and reschedule the job. The error information returned by PowerShell is: 'Add-Type : Could not load file or assembly '
Here is my powershell script as well:
# Load WinSCP .NET assembly
#Add-Type -Path "WinSCPnet.dll"
Add-Type -Path (Join-Path $PSScriptRoot "WinSCPnet.dll")
# Declare variables
$date = Get-Date
$dateStr = $date.ToString("yyyyMMdd")
# Define $filePath
$filePath = "C:\coverageverifier_scripts\TEST_cvgver.20190121.0101"
# Write-Output $filePath
# Set up session options for VERISK TEST/ACCEPTANCE SFTP SERVER
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::Sftp
HostName = "secureftpa.iso.com"
UserName = "account"
Password = "pw"
SshHostKeyFingerprint = "ssh-rsa 1111 xxx/xxxxxxxxx+3wuWNIkMY5GGgRObJisCPM9c9l7yw="
}
$session = New-Object WinSCP.Session
$session.ExecutablePath = "C:\WinSCP\WinSCP.exe"
try
{
# Connect
$session.Open($sessionOptions)
# Transfer files
$session.PutFiles($filePath,"/").Check()
}
finally
{
$session.Dispose()

Your Add-Type call does not include the path to the WinSCPnet.dll.
If you have the WinSCPnet.dll in the same folder as your PowerShell script, use this syntax:
Add-Type -Path (Join-Path $PSScriptRoot "WinSCPnet.dll")
Or use a full path.
See also Loading assembly section in WinSCP .NET assembly article on Using WinSCP .NET Assembly from PowerShell.

Related

cmd agent job shows success but does nothing to the file

I have a powershell script that launches an Excel macro to refresh pivot tables and data sources, it works fine when run manually or from cmd.
when run from Sql Agent job it succeeds without performing the Excel refresh.
I call the script with this command in the job step:
powershell -command "&'C:\rapport_declaratif\REFRESH_3.ps1'"
I tried calling it with powershell, with cmd, with xp_cmdshell but nothing seems to work.
I even called it differently, for exp when I call it with this command:
cmd.exe /c "C:\rapport_declaratif\REFRESH_3.ps1"
it runs forever.
I also googled and found that I have to create this folder:
C:\Windows\SysWOW64\config\systemprofile\DeskTop
I did and it didn't solve the problem.
Below is my powershell script:
# Open Excel file
$excel = new-object -comobject excel.application
$filePath = "C:\rapport_declaratif\Rapport_Declaratif.xlsm"
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $true
$excel.DisplayAlerts = $false
$worksheet = $workbook.worksheets.item(1)
#Write-Host "Running macro in excel to refresh data."#
$excel.Run("Refresh_ALL")
Start-Sleep -s 30
#Write-Host "data refreshed."#
$workbook.save()
# Write-Host "saved."#
$workbook.close()
$excel.quit()
#Write-Host "Closed Excel"#

Getting an error when trying to execute powershell code via a SQL Agent job

I've setup a SQL Server 2016 agent job that has 2 steps that is executed by the same service account, Step 1 executes an SSIS package that writes 2 files out to a share. Step 2 executes embedded powershell code that combines these 2 files into a single file and creates a file on that same share where the 2 files were created by SSIS. When I execute the job, Step 1, the SSIS package completes successfully and creates the 2 files on this share. But when Step 2 executes I get the error below. Just a point of info, when I run this script locally from my windows 10 box, I have no issues.
I guess my question is, if SSIS can execute successfully with the same service account can this be a permissions issue for powershell scripts? I'm not a server admin so if this is a stupid questions please forgive my ignorance. Any help/direction anyone can provide would be appreciated.
Message
Executed as user: XXX\sqlsvc02. The job script encountered the following errors. These errors did not stop the script: A job step received an error at line 12 in a PowerShell script. The corresponding line is 'Get-Content $pathCounts, $pathDetails | Set-Content $outFile'. Correct the script and reschedule the job. The error information returned by PowerShell is: 'Cannot find path '\xxx\shared\MonthlyReports\BoundPoliciesAddedAtFaultEndorsementWithin10Days_Counts.csv' because it does not exist. ' A job step received an error at line 12 in a PowerShell script. The corresponding line is 'Get-Content $pathCounts, $pathDetails | Set-Content $outFile'. Correct the script and reschedule the job. The error information returned by PowerShell is: 'Cannot find path '\xxx\shared\MonthlyReports\BoundPoliciesAddedAtFaultEndorsementWithin10Days_Details.csv' because it does not exist. '. Process Exit Code 0. The step succeeded.
Here is my powershell script:
# Define variables
$path = '\\xxx\shared\MonthlyReports'
$pathCounts = Join-Path -Path $path -ChildPath 'BoundPoliciesAddedAtFaultEndorsementWithin10Days_Counts.csv'
$pathDetails = Join-Path -Path $path -ChildPath 'BoundPoliciesAddedAtFaultEndorsementWithin10Days_Details.csv'
$date = Get-Date
$dateStr = $date.ToString("yyyyMM")
# Define combined file name
$outFile = Join-Path $path -ChildPath("BoundPoliciesAddedAtFaultEndorsementsWithin10Days_" + $dateStr + ".csv")
# Execute combine files code
Get-Content $pathCounts, $pathDetails | Set-Content $outFile
Here is an image of what Step #2 looks like:

Can't start script on remote server from shared resources

I'm trying to write a script in Power Shell to connect to a remote server and execute a .bat file. Since I wanted to do this for more than one server I thought I could place the .bat file on another server which shares ist resources and call it from there, but that does not work. When I place the .bat file in my temp folder and execute it via the script it works. However trying to execute it from the shared resources does not. Why is that?
Note: I can manually start the process via the Task-Manager that starts the .bat file in the shared resources and it works.
script:
$CompName = "myotherserver"
$cred = get-credential
$process = get-wmiobject -query "SELECT * FROM Meta_Class WHERE __Class = 'Win32_Process'" -namespace "root\cimv2" -computername $CompName -credential $cred
$results = $process.Create( "cmd.exe `/c \\mysharedresc\temp\started.bat" )
started.bat:
echo started > c:\temp\started.txt
If you need more annotations or Information please ask for it.
Edit: Working means for me it creates the started.txt in C:\temp. Not working means it does not (but in this case there is no error given.)

How to download newer files using WinSCP and save them to two local folders?

I have file in a folder (ftp_region) whose contents is similar to data in my FTP.
How to download newer files from my FTP and save them to two local folders (ftp_region and other folder)
For now, I use this:
open "my ftp address"
get -neweronly "..." "..."
You cannot do this with a plain WinSCP scripting.
You better use the WinSCP .NET assembly. It allows you to process the downloaded files.
An example code in PowerShell:
# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::Ftp
HostName = "ftp.example.com"
UserName = "user"
Password = "password"
}
Write-Host "Connecting..."
$session = New-Object WinSCP.Session
# $session.SessionLogPath = "C:\path\to\log\sync.log"
$session.Open($sessionOptions)
$remotePath = "/remote/path"
$localPathPrimary = "C:\backup\primary"
$localPathSecondary = "C:\backup\secondary"
Write-Host "Synchronizing..."
$result =
$session.SynchronizeDirectories(
[WinSCP.SynchronizationMode]::Local, $localPathPrimary, $remotePath,
$False)
$result.Check()
Write-Host "Copying downloaded files to secondary backup..."
foreach ($download in $result.Downloads)
{
$filename = (Split-Path -Leaf $download.Destination)
$localFilePathSecondary = (Join-Path $localPathSecondary $filename)
Copy-Item $download.Destination $localFilePathSecondary
Write-Host "File $filename archived to both folders."
}
The code is based on an official example Deleting remote files after successful remote to local synchronization.

Set PW never expire for a list of server

I am looking to set "password never expires" for a local Windows user account, for a list of servers in a text file. So far, I found this command line below, but it only works local on single computer. How can I incorporate this into a VBscript, PowerShell, or batch file to apply on a list of servers in a text file?
WMIC USERACCOUNT WHERE "Name='accountname'" SET PasswordExpires=FALSE
This code should do it:
# 1. Define in-line array of servers
$ServerList = #('localhost', 'localhost', 'localhost');
# 2. Define account name
$AccountName = 'test';
# 3. For each server, set the account to expire
foreach ($Server in $ServerList) {
$Account = Get-WmiObject -ComputerName $Server -Class Win32_UserAccount -Filter "Name = '$AccountName'";
$Account.PasswordExpires = $false;
[void] $Account.Put();
}
If you want to import a text file that contains the server names, you can simply change the first line to this:
$ServerList = Get-Content -Path c:\path\to\text\file.txt;
An alternative method would be to use Invoke-Command, however this requires that you first configure PowerShell Remoting in your environment.
# 1. Define in-line array of servers
$ServerList = #('localhost', 'localhost', 'localhost');
# 2. Define the block of code to deploy (a PowerShell ScriptBlock)
$ScriptBlock = {
$AccountName = 'test';
$Account = Get-WmiObject -Class Win32_UserAccount -Filter "Name = '$AccountName'";
$Account.PasswordExpires = $false;
[void] $Account.Put();
};
# 3. Deploy the ScriptBlock to the array of servers
Invoke-Command -ComputerName $ServerList -ScriptBlock $ScriptBlock;
To configure PowerShell Remoting, run the Enable-PSRemoting -Force command on each computer. You can also use Active Directory Group Policy to enable PowerShell Remoting / Windows Remote Management (WinRM).
wmic can be run against remote hosts via the /node parameter:
wmic /node:HostA,HostB useraccount where "Name='accountname'" ...

Resources