Run string from command line with parameters and switches using powershell - powershell

I have a powershell script that copies a file to a remote computer, and I need to execute it from a command line and with arguments/parameters.
Here is what I have...and I can't get it to work:
Get-Content C:/temp/list.txt |
ForEach-Object {
Try {
$source = "\\server\folder\my application 1.2.1.EXE"
$destination = "\\" + $_ + "\C$\temp\"
New-Item -Path $destination -ItemType Directory -Force
Copy-Item -path $source -Destination $destination -force | Out-Null
& "$_ +"\C:\temp\my application 1.2.1.EXE" Location=07 /s" ##| Out-Null
$status = "Success"
}
Catch {
$status = "Failed"
}
"$_, $status" | out-file -filepath c:\temp\restult1.csv -Append -Encoding ascii
}

I resolved it.
Get-Content C:/temp/list.txt |
ForEach-Object {
Try {
$source = "\\server\folder\my application 1.2.1.EXE"
$destination = "\\" + $_ + "\C$\temp\"
New-Item -Path $destination -ItemType Directory -Force
Copy-Item -path $source -Destination $destination -force | Out-Null
Invoke-Command -ComputerName $_ -ScriptBlock {
& cmd.exe /c "C:\temp\my application 1.2.1.EXE" Location=07 /s ##| Out-Null
}
$file = $destination + "my application 1.2.1.EXE"
Remove-Item $file -Force
$status = "Success"
}
Catch {
$status = "Failed"
}
"$_, $status" | out-file -filepath c:\temp\restult1.csv -Append -Encoding ascii
}

Related

For loop with list not working as expected Powershell

I'm trying to create a powershell script which checks a log file for lines of text and if the line exists restarts a service and resets/archives the log. I got it working before with 1 "checkstring" if you will, but I've been struggling to get it to work with a list of strings. Could anyone help me figure out where I'm going wrong?
This is the code I'm currently using:
$serviceName = "MySQL80"
$file = "test.txt"
$pwd = "C:\tmp\"
$checkStrings = New-Object System.Collections.ArrayList
# Add amount of checkstrings
$checkStrings.add("Unhandled error. Error message: Error retrieving response.")
$checkStrings.add("Unhandled error. Error message: Error retrieving response. Second")
$logName = "ServiceCheck.log"
$backupFolder = "Archive"
$logString = (Get-Date).ToString("ddMMyyyyHHmmss"), " - The service has been reset and the log moved to backup" -Join ""
Set-Location -Path $pwd
if(Test-Path -Path $file) {
if(Test-Path -Path $backupFolder) {
} else {
New-Item -Path $pwd -Name $backupFolder -ItemType "director"
}
foreach ($element in $checkStrings) {
$containsWord = $fileContent | %{$_ -match $element}
if ($containsWord -contains $true) {
Restart-Service -Name $serviceName
$backupPath = $pwd, "\", $backupFolder, "\", $date, ".log" -join ""
$currentFile = $pwd, "\", $file -join ""
Copy-Item $currentFile -Destination $backupPath
Get-Content $currentFile | select-string -pattern $checkString -notmatch | Out-File $currentFile
if(Test-Path -Path $logName) {
Add-Content $logName $logString
} else {
$logString | Out-File -FilePath $logName
}
}
}
}

Powershell - ForEach loop running twice on the same path instead of moving on next one

I am looking to move files from various paths to E:\backups\folder1\export, E:\Backups\folder2\backups, E:\backups\folder3\export and using below code...but strangely it runs twice on the same path and doesn't move to next path and duplicates the output too.
Cls
$date = Get-Date -Format "yyyMMdd_hhmmss"
#$sourcePath = "C:\Program Files\Atlassian\Application Data\JIRA\export\"
#$destPath = "E:\Backup\Jira\export"
$config = Import-Csv -Path 'E:\Backup\Scripts\Atlassian_Backups.csv'
#Write-Output $config
Start-Transcript -Path E:\Backup\Logs\Atlassian_backupMove.log
foreach ($item in $config)
{
Write-Host "Moving all files in '$($sourcePath)' to '$($destPath)'"
$fileList = #(Get-ChildItem -Path "$($sourcePath)" -File)
#Write-Output $fileList
if ($filelist.count -gt 0)
{
Write-host $filelist.Count
ForEach($file in $fileList)
{
try {
#Move-Item -Path $file.FullName -Destination ((Split-Path
$file.FullName).Replace("$($sourcePath)",$destPath)) -Force -ErrorAction Stop
Copy-Item -Path $file.FullName -Destination $destPath -Verbose -Force -ErrorAction Stop |
Format-table
}
catch{
Write-Warning "Unable to move '$($file.FullName)' to '$(((Split-Path
$file.FullName).Replace("$($sourcePath)",$destPath)))': $($_)"
return
}
}
}
}
Stop-Transcript
Rename-Item E:\Backup\Logs\Atlassian_backupMove.log
E:\Backup\Logs\Atlassian_backupMove_$date.log
write-host Log File has been created and renamed to Atlassian_backupMove_$date.log'
below was changed in my code and worked well.
{#Move-Item -Path $file.FullName -Destination ((Split-Path
$file.FullName).Replace("$($sourcePath)",$destPath)) -Force -ErrorAction Stop
Copy-Item -Path $file.FullName -Destination $item.destPath -Verbose -Force -
ErrorAction Stop | Format-table } catch{ Write-Warning "Unable to move
'$($file.FullName)' to '$(((Split-Path
$file.FullName).Replace("$($item.sourcePath)",$item.destPath)))': $($_)" return
}

Unable to run batch file from powershell script when it is a scheduled task

I am trying to run a batch file from a powershell script that is a scheduled task. The script sets up a filewatcher and in the action block it calls a batch file using start-process. If I run the action block as a script it works correctly. If I run the whole powershell script from Visual Studio Code, it works correctly. When I schedule the script as a task, the batch file doesn't run. The task is set to run under my account, I am a local administrator and I run it with highest privileges. Get-Executionpolicy returns Remotesigned. The task action block starts powershell with the parameters '-noexit -file "C:\Users\wheckle\Documents\CTA\Projects\Test Automation\windowsTest\watcher\newwatcher.ps1" -ExecutionPolicy Bypass.
I use the -Wait option on the start-process cmdlet. It waits from Visual Studio Code; but, it doesn't wait for the command to finish as a task.
$systemBase = "C:\Users\auser\Documents\CTA\Projects\Test Automation\windowsTest\"
$driverFile = $systemBase + "Generate\Driver\chromedriver.exe"
$logfileName = "TestAutomation.log"
$requestFile = "TestRequest.txt"
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path= ($systemBase+"dropfile")
$watcher.EnableRaisingEvents = $true
$watcher.IncludeSubdirectories = $true
$action =
{
if ($event.SourceEventArgs.ChangeType -eq 'Created') {
$appFile = ($event.SourceEventArgs.FullPath | split-path -Parent | split-path -Leaf)
$dropBase = $systemBase + "dropfile\" + $appFile +"\"
# check for log file
if (!(Test-Path -Path ($systemBase + $logfileName) -PathType "Leaf")) {
new-item -Path ($systemBase + $logfileName) -ItemType "File"
}
# Log Starting Project
"Now Starting the Job for "+$appFile + " at "+ (Get-Date -format "MM-dd-yyyy-HH-mm.fff") | Out-File -FilePath ($systemBase + $logfileName) -Append
Get-ExecutionPolicy | Out-File -FilePath ($systemBase + $logfileName) -Append
# Check for group and email files
if ((Test-Path -Path ($dropBase + $requestFile) -PathType "Leaf")) {
"Executing for "+$appFile + " at "+ (Get-Date -format "MM-dd-yyyy-HH-mm.fff") | Out-File -FilePath ($systemBase + $logfileName) -Append
# Create execution directory for job
if (!(Test-Path -Path ($systemBase + "Results\" + $appFile))) {
$resultsDir = new-item -Path ($systemBase+ "Results\" +$appFile) -ItemType "directory"
} else {
$resultsDir = Get-Item -Path ($systemBase+ "Results\" +$appFile)
}
"Creating project dir for "+$appFile + " at "+ (Get-Date -format "MM-dd-yyyy-HH-mm.fff") | Out-File -FilePath ($systemBase + $logfileName) -Append
#Create directory for job
$projectDir = new-item -Path ($resultsDir.FullName+"\"+(Get-Date -format "MM-dd-yyyy-HH-mm.fff")) -ItemType "directory"
#Copy jar file into executable
$jarFile = $systemBase + "Generate\" +$appfile+"\JarFile"
$jarFiles = Get-ChildItem -Path $jarFile
if (( $null -eq $jarFiles) -or ($jarFiles.count -eq 0)) {
(Get-Date -format "MM-dd-yyyy HH:mm ")+ "Exiting because of missing jar file for " + $appFile | Out-File -FilePath ($systemBase + $logfileName) -Append
Return 0
}
Copy-Item -Path $jarFiles[0].FullName -Destination $projectDir
# Create bat file
$batFile = New-Item -Path $projectDir.FullName -Name "run-automation.bat" -ItemType "file"
#create execute line
$batString = '"%JAVA_HOME%\bin\java" -jar "'+$projectDir + "\" + $jarFiles[0].Name+'" '
$batString += Get-Content -Path ($dropBase + $requestFile) -TotalCount 1
#add additional lines
$batDir = $systemBase + "Generate\" + $appFile +"\batfile"
if (Test-Path -Path ($batDir)) {
if (Test-Path -Path ($batDir+"preBat.txt")) {
Get-Content -Path ($batDir+"preBat.txt") | Set-Content -Path $batFile.FullName
}
$batString | Out-File -FilePath $batFile.FullName -Append
if (Test-Path -Path ($batDir+"preBat.txt")) {
Get-Content -Path ($batDir+"postBat.txt") | Add-Content -Path $batFile.FullName
}
} else {
$batString | Out-File -FilePath $batFile.FullName
}
# add config directory
$configDir = New-Item -Path $projectDir -Name "config" -ItemType "directory"
Copy-Item -Path $driverFile -Destination $configDir.FullName
Copy-Item -Path ($systemBase+"Generate\"+$appFile+"\config\*") -Destination $configDir.FullName
$emailStr = "toEmail="
Write-Host
if (Test-Path -Path ($configDir.FullName+"\testconfig.properties")) {
$emailStr += (Get-Content -Path ($dropBase+$requestFile) -TotalCount 2)[-1]
$emailStr | Add-Content -Path ($configDir.FullName+"\testconfig.properties")
} else {
$emailStr += (Get-Content -Path ($dropBase+$requestFile) -TotalCount 2)[-1]
$emailStr | Set-Content -Path ($configDir.FullName+"\testconfig.properties")
}
Set-Location $projectDir
$exeResults = new-item -Path $projectDir.FullName -Name "ExcutionResults.txt" -ItemType "file"
"Starting Batch Process for "+$appFile + " at "+ (Get-Date -format "MM-dd-yyyy-HH-mm.fff")+ " file "+ $batFile.FullName| Out-File -FilePath ($systemBase + $logfileName) -Append
Start-Process -FilePath $batFile.FullName -Wait -NoNewWindow | Out-File -FilePath $exeResults.FullName
"Ended Batch Process for "+$appFile + " at "+ (Get-Date -format "MM-dd-yyyy-HH-mm.fff") | Out-File -FilePath ($systemBase + $logfileName) -Append
Remove-Item -Path ($dropBase + $requestFile)
} else {
"Invalid file for "+$appFile + " at "+ (Get-Date -format "MM-dd-yyyy-HH-mm.fff") | Out-File -FilePath ($systemBase + $logfileName) -Append
}
}
}
Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action -SourceIdentifier FSCreate1

create symboliclink with powershell

I write script below to compare and create symboliclink with powershell.
$Source = "C:\Transcode\Powershell\abc&1"
$Destination = "C:\Transcode\Powershell\abc&2"
$filter = '*.txt'
$tmp = "$Source\tmp.log"
$log = "$Source\delete.log"
function New-SymLink ($link, $target)
{
if ($PSVersionTable.PSVersion.Major -ge 5)
{
New-Item -Path $link -ItemType SymbolicLink -Value $target
}
else
{
$command = "cmd /c mklink "
invoke-expression "$command ""$link"" ""$target"""
}
}
Get-ChildItem -Path $Source -Filter $filter -Recurse |
ForEach-Object {
$name=$_.BaseName
$ext=$_.Extension
$fileS=$_.FullName
$fileD="$Destination\$name$ext"
IF (Get-Content $tmp | Where-Object{$_ -match "$name"}){
New-SymLink ("""""$fileD""""","""""$fileS""""")
}
}
I get trouble with file name what contains symbol &.
I can create link by call command promt like this
cmd /c mklink """$Destination\$name$ext""" """$fileS"""
But I want to use function.
Can you help me resovle it
Try this (only partly tested) streamlined version which
escapes the & in $command with a caret ^&
removes redundancy and possibly unneeded quoting
## Q:\Test\2019\04\23\SO_55803869.ps1
$Source = "C:\Transcode\Powershell\abc&1"
$Destination = "C:\Transcode\Powershell\abc&2"
$filter = '*.txt'
$tmp = Get-Content "$Source\tmp.log"
$log = "$Source\delete.log"
function New-SymLink ($link, $target){
if ($PSVersionTable.PSVersion.Major -ge 5){
New-Item -Path $link -ItemType SymbolicLink -Value $target
} else {
$command = 'cmd.exe /c mklink "{0}" "{1}"' -f $link,$target
invoke-expression $command.Replace('&','^&')
}
}
Get-ChildItem -Path $Source -Filter $filter -Recurse | ForEach-Object {
$fileD= Join-Path $Destination $_.Name
IF ($tmp | Where-Object {$_ -match $_.BaseName} ) {
New-SymLink $fileD $_.FullName
}
}

PowerShell Move-Item $filename

I searched, i googled.. about to smash my head on the table
how come this will not work?
move-Item $path$file $targetdir
it gives me an error
Move-Item : An object at the specified path C:\Repository\test.csv
does not exist.
now if i debug this and i output using
write-output move-Item $path$file $targetdir
and take that output and paste it (file name with path and destination) it works!
and trust me the file is there. =\
Code below
$path = 'C:\test\'
$TimeStamp = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$LogFile = Get-Date -Format "MM_dd_yyyy"
$targetdir = "C:\test\Uploaded\"
#Get-ChildItem -path $path\* -Include *.csv | foreach-object {$_.Fullname} | Format-Table name -hidetableheaders | Out-File $path\list.txt
Get-ChildItem -path $path\* -Include *.csv | Format-Table name -hidetableheaders | Out-File $path\list2.txt
get-content C:\test\list2.txt | where {$_ -ne ""} | out-file C:\test\list.txt
Remove-Item C:\test\list2.txt
$list = get-content C:\test\list.txt
foreach ($file in $list)
{
$ftp = "ftp://REMOVED/$file"
"ftp url: $ftp"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
"Uploading $file..."
$succeeded = $true;
& {
trap { $script:succeeded = $false; continue }
$webclient.UploadFile($uri, $path+$file)
}
if ($succeeded)
{
echo $file 'Was successfully uploaded!' $Timestamp >> logfile$LogFile.log
move-Item -path $path$file -destination $targetdir
#test-path $path$file
}
else
{
echo $file 'Was not successfully uploaded, will retry later' $Timestamp >> logfile$LogFile.log
}
}
exit
Basics are:
Test-Path before you move it (file and destination)
Move the file, ensure you have permission (force it to move)
so:
echo $targetdir
echo "$path$file"
if (!(Test-Path $targetdir)) {
New-Item -ItemType directory $targetdir
}
if(Test-Path "$path$file") {
Move-Item "$path$file" $targetdir -Force
} else {
echo "file does not exist"
}
If you loop over a collection you have to use the ".FullName" property of the object:
Get-ChildItem $path | ForEach-Object { Move-Item $_.FullName $targetdir -Force }
Does the target directory already exist? I believe Move-Item will fail if the target directory doesn't exist. If that's the case, you can simply test for existence of the directory beforehand and then create as necessary.
If (!(Test-Path -Path $targetdir)) {
New-Item -ItemType directory -Path $targetdir
}
This worked for me. Thank you #TheMadTechnician. Hopes this helps everyone
$TimeStamp = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$LogFile = Get-Date -Format "MM_dd_yyyy"
$path='C:\test\'
$targetDir = 'C:\test\Uploaded\'
$fileList = Get-ChildItem $path*.csv
If(!(Test-Path $TargetDir)){New-Item -ItemType Directory -Path $TargetDir|Out-Null}
$fileList | Select -ExpandProperty Name | Out-File 'C:\test\list.txt'
$list = get-content C:\test\list.txt
foreach ($file in $list)
{
$ftp = "ftp://REMOVED/$file"
"ftp url: $ftp"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
"Uploading $file..."
$succeeded = $true;
& {
trap { $script:succeeded = $false; continue }
$webclient.UploadFile($uri, $path+$file)
}
if ($succeeded)
{
echo $file 'Was successfully uploaded!' $Timestamp >> logfile$LogFile.log
move-Item -path $path$file -destination $targetdir$Timestamp"_"$file
#test-path $path$file
}
else
{
echo $file 'Was not successfully uploaded, will retry later' $Timestamp >> logfile$LogFile.log
}
}
exit
How about this then:
ForEach($File in $List){
Join-Path $path $file | Move-Item -Dest $Targetdir
}
Edit: Also... your creation of list.txt, it bothered me so I had to comment. Format-Table should be used for formatting text, not for selecting a value to output to a file. There's a better way to do that, consider this alternative:
Get-ChildItem "$path*.csv" | Select -ExpandProperty Name | Out-File $pathlist.txt
Since you say that $path = 'C:\test\' you are adding extra backslashes in there that may cause issues for some commands.
Edit2: Ok, if that doesn't work, why not work with the files themselves instead of outputting to a file, importing from that file, and then working with things.
$path='c:\test\'
$TargetDir = 'c:\test\NewDir'
$FileList = Get-ChildItem $path*.csv
If(!(Test-Path $TargetDir)){New-Item -ItemType Directory -Path $TargetDir|Out-Null}
$FileList | Move-Item -Destination $TargetDir
Then if you really want a list of those file names just pipe $FileList to Select and then to Out-File
$FileList | Select -ExpandProperty Name | Out-File 'C:\Test\list.txt'
Here, look through this and see if there's anything you like. I made a few changes, such as declaring paths at the beginning for everything, I moved the WebClient object creation outside of the loop, and changed how things are displayed on screen. Plus I skip the entire exporting to text file and re-importing it.
$path = 'C:\test'
$ftpaddr = 'ftp://ftp.example.com/uploads'
$TimeStamp = Get-Date -Format "MM/dd/yyyy hh:mm:ss tt"
$LogFile = Get-Date -Format "MM_dd_yyyy"
$LogDir = "C:\Test\Logs"
If(!(test-path $LogDir)){New-Item -ItemType Directory -Path $LogDir | Out-Null}
$targetdir = 'C:\test\Uploaded'
If(!(test-path $targetdir)){New-Item -ItemType Directory -Path $targetdir | Out-Null}
$list = Get-ChildItem -path $path\* -Include *.csv
$webclient = New-Object System.Net.WebClient
"ftp url: $ftpaddr"
foreach ($file in ($list|select -ExpandProperty Name))
{
$uri = New-Object System.Uri(("$ftpaddr/$file"))
Write-Host "Uploading $file... " -NoNewline -ForegroundColor White
$succeeded = $true
& {
trap { $script:succeeded = $false; continue }
$webclient.UploadFile($uri, "$Path\$file")
}
if ($succeeded)
{
Write-Host "Success!" -ForegroundColor Green
"$Timestamp`t$File was successfully uploaded!" | Out-File "$logdir\logfile$LogFile.log" -Append
move-Item -path "$path\$file" -destination $targetdir
}
else
{
Write-Host "Failed! Will retry later." -ForegroundColor Red
"$Timestamp`t$File was not successfully uploaded, will retry later" | Out-File "$logdir\logfile$LogFile.log" -Append
}
}