If I run the script below it will perform all the tasks that I need it to. I need the task to run every 15 seconds in a loop. When I add a loop of any type, the loop gets stuck on only a portion of the script an no longer functions as expected. I'm looking to loop the entire script top to bottom. The current script does not have any loops at this time. Any help would be greatly appreciated.
# Syslog Management. Automate has a max size of 977KB before it dumps everything into a file called Syslogold.txt
# If Syslogold.txt already exists it will be overwriten and logs will be gone.
# Script below will move syslogold.txt into syslog folder where it will be renamed to Syslog-(CurrentDate).TxT
# When ever a new Syslogold.txt is generated by Automate, this script will append the output to a daily file in a monthly folder.
# On the first day of every month, the previous month will be zipped and archived.
#
$LastMonth = (Get-Date).AddMonths(-1).ToString('MMM-yyyy')
$CurrentSyslogFolder = "C:\Windows\LTsvc\Syslogs\Syslogs-$(Get-Date -Format "MMM-yyyy")"
$OldDirectory = "C:\Windows\LTsvc\Syslogs\Syslogs-$LastMonth"
$CurrentLog = "Syslog-$(Get-Date -Format "dd-MMM-yyyy").txt"
$OldLog = "C:\Windows\LTSvc\syslogold.txt"
$SyslogArchive = "C:\Windows\LTSvc\Syslogs\Archive\Syslog-$LastMonth.zip"
do{
$TestPath01 = Test-Path -Path $CurrentSyslogFolder
$TestPath02 = Test-Path -Path $CurrentSyslogFolder\$CurrentLog
$TestPath03 = Test-Path -Path $OldLog
$TestPath04 = Test-Path -Path $OldDirectory
if($TestPath01)
{
write-host "Syslog directory current."
}
else
{
write-host "Current syslog directory is for last month. Creating new folder."
New-Item -ItemType Directory -Force -Path $CurrentSyslogFolder
}
if(($TestPath02) -and ($TestPath03))
{
write-host "Automate syslog archive found"
write-host "Daily syslog Found."
write-host "Appending Automate archive with daily syslog"
Add-Content -Path $CurrentSyslogFolder\$CurrentLog -Value ""
Get-Content -Path $OldLog | Add-Content -Path $CurrentSyslogFolder\$CurrentLog
Remove-Item -Path $OldLog
start-sleep -Seconds 15
}
else
{
write-host "Automate syslogs active."
write-host "Waiting for Automate to archive syslogs."
if ($TestPath03)
{
Write-Host "Automate has completed archiving Syslogs."
Write-Host "Moving archive to daily syslog."
Write-host "Daily syslog missing. Creating daily syslog now"
Move-Item $OldLog -Destination $CurrentSyslogFolder\$CurrentLog
}
}
if($TestPath04)
{
write-host "Last months directory found."
Write-Host "Compressing last months directory"
Compress-Archive -Path "$OldDirectory" -DestinationPath "$SyslogArchive"
Write-host "Moving compressed directory to archive"
Write-host "Cleaning up files"
Remove-Item -Path "$SyslogDirectory\Syslogs-$LastMonth" -Recurse
Write-host "Cleanup completed"
start-sleep -Seconds 15
}
else
{
Write-host "Will try again in 15 seconds"
start-sleep -Seconds 15
}
}until($infinity)
To be honest the best way would be Scheduled Task ScheduledTask
But you can also use do or while
do{ YOURSCRIPT start-sleep -Seconds 15 }until($infinity)
Related
I need help on a specific issue with Powershell.
What I am trying to do is that starting multiple services one bye one and after successfully start process, I need to copy some files from one location to another. These files are created only after the service/app is up. I need to check it from a string in a text file (like "Service successfully started").
I tried to make a for-each loop but because of copying and text check locations are different, I couldn't manage to do it. And honestly, I don't have much information about nested loops. Maybe you can give me some ideas to make this work.
For examples, for 1 service;
Source folder file locations;
C:\sourcepath\location1\folder\abc.dat
C:\sourcepath\location1\folder\cde.dat
txt file which needs to be checked if there is a string line called "Service successfully started" (to understand the service-app successfully started)
C:\sourcepath\folder1\logs\logfile.txt
Destination folder file locations
D:\destinationpath\location1\ (abc.dat and cde.dat files should be in same folder)
--- The flow should be like that;
Start a service
Make sure it's up as checking the txt file string
After controls, make copying process from source folder to destination for the specified files (as creating destination folder based on source folder)
Stop the service
After checking it's status as stopped, again start another service and do the same processes until the last service but for different locations
For example, location1 should be location2 and then location3 but the file names are the same. Also destination folder should be created according to source folder.
Even any directions will be helpful.
Edit1:
So far, I could write code.
[array]$serviceNames = "lfsvc", "iphlpsvc"
[array]$app = "app1", "app2"
$sourceStart = "C:\Source\"
$destinationStart = "C:\Target\"
$logs = "\logs"
$sourceFull = $sourceStart+$app.Get(0)+"\data"
$destinationFull = $destinationStart+$app.Get(0)
ForEach ($serviceNames in $serviceNames)
{
Start-Service $serviceNames -ErrorAction SilentlyContinue;
$text = Select-String -Path $sourceStart+$app.Get(0)+$logs\log.txt -Pattern "Service successfully started"
if ($text -ne $null)
{
md $destination;
Copy-Item -Path $sourceFull\123.txt -Destination $destinationFull\123.txt
Copy-Item -Path $sourceFull\456.txt -Destination $destinationFull\456.txt
}
}
I need to point other $app values in a row as pointing other $serviceNames values accordingly.
I need to take control the if values if wait till it shows the service successfully started line
Thanks
Edit2:
If I want to write it in long way, that should be something like that. (Ofc, if I can check the string from a specified text file, it would be gr8)
I need to shorten the codes
[array]$serviceNames = "aService", "bService"
Start-Service $serviceNames[0] -ErrorAction SilentlyContinue;
Start-Sleep -Seconds 75;
md "C:\Dest\aService\fld";
Copy-Item -Path "C:\Source\aService\fld\123.txt" -Destination "C:\Dest\aService\fld\123.txt";
Copy-Item -Path "C:\Source\aService\fld\456.txt" -Destination "C:\Dest\aService\fld\456.txt";
Copy-Item -Path "C:\Source\aService\fld\789.txt" -Destination "C:\Dest\aService\fld\789.txt";
Stop-Service $serviceNames[0] -ErrorAction SilentlyContinue;
Start-Sleep -Seconds 15;
Start-Service $serviceNames[1] -ErrorAction SilentlyContinue;
Start-Sleep -Seconds 75;
md "C:\Dest\bService\fld";
Copy-Item -Path "C:\Source\bService\fld\123.txt" -Destination "C:\Dest\bService\fld\123.txt";
Copy-Item -Path "C:\Source\bService\fld\456.txt" -Destination "C:\Dest\bService\fld\456.txt";
Copy-Item -Path "C:\Source\bService\fld\789.txt" -Destination "C:\Dest\bService\fld\789.txt";
Stop-Service $serviceNames[1] -ErrorAction SilentlyContinue;
Start-Sleep -Seconds 15;
I think I have an idea of what you want.
[array]$serviceNames = "lfsvc", "iphlpsvc"
[array]$apps = "app1", "app2"
$sourceStart = "C:\Source\"
$destinationStart = "C:\Target\"
$logs = "\logs"
# main loop, which loops over the apps
foreach($app in $apps)
{
$sourceFull = $sourceStart + $app + "\data"
$destinationFull = $destinationStart + $app
# each app will iterate over all of the services
ForEach ($name in $serviceNames)
{
# uses -passthru to get the service object, and pulls its status from that. Will cause any errors to terminate the script
$status = (Start-Service $name -ErrorAction Stop -PassThru).Status
# this while loop will cause it to pause until the service is in "running" state
while($status -ne "Running") {Start-Sleep -Seconds 5; Get-Service $name}
$text = Select-String -Path $($sourceStart + $app + $logs + "\log.txt") -Pattern "Service successfully started"
# check to see if the $text variable is null or empty, if not, do the thing
if (![string]::IsNullOrEmpty($text))
{
if(!(Test-Path -Path $destinationFull)){New-Item -ItemType Directory -Path $destinationFull}
Get-Content -Path "$sourceFull\123.txt" | Add-Content -Path "$destinationFull\123.txt"
Get-Content -Path "$sourceFull\456.txt" | Add-Content -Path "$destinationFull\456.txt"
}
# stops the service
$status = Stop-Service $name -PassThru
# pauses until the service is stopped
while($status -ne "Stopped") {Start-Sleep -Seconds 5; Get-Service $name}
}
}
something like this?
i need some help.
I need a powershell script with following actions.
The script starts and firts checks whether file 1 is available. If this is available, go to step 2. If file 1 is not available, the script should end.
The script checks whether file 2 exists. If file 2 is available, the script should end; if file 2 is not available, go to step 3.
The script checks whether a program X is running. If YES it should exit the program and copy file 3 into a folder. If program X is not running, it should copy file 3 immediately.
Very important! If in step 2 the file 2 exist, the script must quit.
This what i have but even if file 2 is present, it copies the files.
$Path = "\\xyz\trigger1.txt"
$Path2 = "$env:userprofile\xyz\trigger2.txt"
if ((Test-Path $Path) -and !(Test-Path $Path2)) {
"trigger1.txt exist"
"trigger2.txt not exist"
if((get-process "XXX" -ea SilentlyContinue) -eq $Null)
{
"not Running"
copy-item "\\xyz\xyz\*" "$env:userprofile\def\" -recurse -ErrorAction SilentlyContinue
start-sleep -s 5
Start-Process -filepath "C:\Program Files (x86)\mno\XXX.exe"
}
else
{
"running"
stop-process -name "XXX" -force
start-sleep -s 5
copy-item "\\xyz\xyz\*" "$env:userprofile\def\" -recurse -ErrorAction SilentlyContinue
start-sleep -s 5
Start-Process -filepath "C:\Program Files (x86)\mno\XXX.exe"
}
}
else
{
"trigger1.txt not exist"
start-sleep -s 5
}
Make sure you're running the script under right user.
Make sure you use -PathType Leaf in Test-Path if you are only looking for files.
Make sure logical operators are working with parentheses to avoid mistakes.
if ((Test-Path $Path -PathType Leaf) -and (-not (Test-Path $Path2 -PathType Leaf))) {
}
I have a sharepoint 2010 list designed with custom solution. It has 3 level folder hierarchy. In the last folder level multiple documents are present as attachments. I want to get all the document attachments from that folder and store it in my local drive, so that it can be migrated to a different platform.
Number of Attachments are around 350000.
My Tasks are:
Creating Folder in my drive.
Getting Attachment ids and create folder with id name, as inputs from a txt file.
Map network drive
Copy attachment from network drive to local folder.
Delete network drive.
These 5 steps are to be repeated for around 350000 attachments.
Kindly let me know if cmdlets can be executed properly one after the other.
$idsFile = "H:\D\Temp\testingid.txt"
$FileStore = "H:\D\Temp\Attachments"
foreach ($line in Get-Content $idsFile) {
$FileCount = 1
$thisappid = $line.Split("`t")
Write-Host $thisappid.GetValue(0)
$FPath = $FileStore + '/' + $thisappid.GetValue(1)
Write-Host $FPath
if (!(Test-Path $FPath)) {
Write-Host "Creating folder.."
$F1 = New-Item -Path $FileStore -Name $thisappid.GetValue(1) -ItemType "directory"
Write-Host $F1
$F2 = New-Item -Path $F1 -Name $thisappid.GetValue(0) -ItemType "directory"
} else {
Write-Host "Folder" $thisappid.GetValue(1) "Already exists"
$SPath = $FileStore + '/' + $thisappid.GetValue(1) + '/' + $thisappid.GetValue(0)
Write-Host $SPath
if (!(Test-Path $SPath)) {
$F2 = New-Item -Path $SPath -Name $thisappid.GetValue(0) -ItemType "directory"
Write-Host $F2
} else {
Write-Host "Folder" $thisappid.GetValue(0) "already exists"
Write-Host "Move to Next.."
}
}
Write-Host $thisappid.GetValue(0)
$id = $thisappid.GetValue(0) -as [int]
Write-Host $id
Write-Host $id.GetType()
net use Y: \\domainName/sites/SiteName/Lists/MyList/Attachments/$id
/Persistent:Yes
Start-Sleep -s 10
$name = Get-ChildItem -Path Y:\ -Name
Start-Sleep -s 10
Copy-Item -Path Y:\$name -Destination $dest
Start-Sleep -s 10
net use Y: /delete /y
Start-Sleep -s 10
$FileCount = $FileCount+1
Write-Host $FileCount
}
I am needing to create a logfile for every action that is performed by this script.
I have attempted to use redirection(>>) however, cannot get the output to actually write to the file.
while($true){
$FromMC = Get-ChildItem -Path "\\x\From MC" -Filter *.mpg
Write-Host "Checking '\\x\From MC' for files" -ForegroundColor Cyan
Write-Host $FromMC.count"Files Found" -ForegroundColor Cyan
Write-Host ""
ForEach($file in $FromMC){
try{
Move-Item -Filter 7ST* -Path $file.Fullname -Destination "\\x\programs\7TH STREET THEATER" -Verbose -Force -ErrorAction Stop
}
catch{...}
Write-Host "Pausing for"$ts.Minutes"minutes..." -ForegroundColor Cyan
Write-Host "Ctrl+C to Stop"
Write-Host ""
Start-Sleep -Seconds $ts.TotalSeconds
}
I expect the output to be exactly as "-verbose" outputs into the shell. Types of output: Write-Host, Verbose, Write-Warning
I feel the solution is extremely simple, and I am just overlooking it.
To log everything that would normally be written to the console, like -verbose you can use Start-Transcript and when you are finished Stop-Transcript.
Example:
Start-Transcript -Path "C:\logs.txt"
#run code you want to capture
Stop-Transcript
I am writing a PowerShell script to delete various files and want to write a function that will prompt the user the percentage completed for each file deletion so that the user doesn't think that the script has crashed. Instead of a progress bar such as {000000.... I would rather have the screen print out a percent number like 10% complete.
#Variables
$Comp_Name = $env:COMPUTERNAME
$DateTime = Get-Date -Format "DMM-dd-yyyy_THH-mm-ss"
#Log Errors
Start-Transcript -Path C:\TEMP\error_Log-$Comp_name-$DateTime.log -Append
# Get the date and time and remove the directory specified in the function
Function Remove-Directory
{
Param([string]$Location)
$files = Get-ChildItem -Path $Location -Recurse | Where-Object {!$_.PSIsContainer}
for ($i = 1; $i -lt $Files.count; $i++) {
Write-Progress -Activity 'Deleting files...' -Status $Files[$i].FullName -PercentComplete ($i / ($Files.Count*100))
Try
{
Get-ChildItem $Location -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue -Verbose 4>&1 | Add-Content C:\TEMP\ModifiedData-$Comp_Name-$DateTime.log
#Write-Output "SUCCESS: $Location has been been Modified Successfully"
}
Catch{Write-Output "ERROR: $Location could be Modified. Please Verify This Location Manually."}
}
}
#Remove the below files from computer
If ($Comp_Name -eq "X")
{
Remove-Directory "C:\Users\X"
}
Stop-Transcript
Write-Output "Script Process Complete. Please Check logs for additional details"
Instead of using -percentcomplete you can use one of the other status indicators
-CurrentOperation "($i / ($Files.Count*100))% complete"
You may wish to round or cast the percentage to an integer, something like:
-CurrentOperation "$([int]($i / $Files.Count*100))% complete"
The order the parameters show up is as follows, so use which one depending on how you want the hierarchy of messages to display.
-Activity
-Status
-CurrentOperation