Capture File Paths with Out-File in Powershell - powershell

I've created a script that I'm using to clean up some drives at my work. I've been asked to create a log and leave it in the source folder after I move files.
Currently, the process is slow because my script creates a text file of files that meet the parameters I input. Once I have verified it, or edited the text file, I allow the script to read the file and keep doing what it needs to do. I'm creating this original text file with Out-File. Obviously, the path of the files change because I'm moving them from one drive to another. I'd like to log their new path but can't seem to figure out how to do this.
The file the script creates and reads from looks like the following:
C:\This\Is\The\Source\Something.rpt
C:\This\Is\The\Source\Somethingelse.bak
C:\This\Is\The\Source\AnotherFile.jpg
I'm looking to create something that will reflect the new path once the files are moved. In the different ways I've tried I either end up with nothing or just the last file copied, which would tell me Out-File is not appending but overwriting each time it gets a new file path.
And the list will just go on. The following is bit from my script I'm having issue with:
$path = Read-Host "What path should I look at?"
$SourceFolder = $path
$files = Get-ChildItem $path -Recurse
| Where-Object {$_.lastwritetime.Date -eq $targetdate}
|Where-Object {$_.PSIsContainer -eq $false}
| ForEach-Object {$_.fullname}
| Out-File $OutFileCopy
$Target = Read-Host "What is the destination?"
Write-Host "Please view the text file created." -foregroundcolor "yellow" -backgroundcolor "red"
Invoke-Item $OutFileCopy
$CopyContinueAnswer = Read-Host "Would you like to continue? Y or N?"
If ($CopyContinueAnswer -eq 'Y') {
$Readfile = Get-Content $outfilecopy
$ReadFile | Where-Object {$_.PSIsContainer -eq $false}
foreach ($file in $ReadFile) {
$logfile = "$Sourcefolder\log.txt"
out-file $logfile
Write-Host "The old path is $File"
$TargetPath = $File.Replace($SourceFolder, $Target)
if (!(Test-Path $TargetPath)){
Write-Host "This is the new path $TargetPath" -foregroundcolor "Magenta"
Write-Host
Copy-Item -path $file -Destination $TargetPath
Write-output $TargetPath | out-file $logfile
}

Out-File by default will overwrite an existing file. If you do not want this to happen, use Out-File -append. I recommend looking at the Microsoft documentation for Out-File; you can find it by typing Get-Help Out-File at any PowerShell prompt, or clicking on the link.

The file that I want to record the new files paths is being created inside the foreach loop. Everytime it stepped to the next file it would recreate the log.txt file and erase what was there previously. Now that I've taken it out of the loop, I don't have the issue of nothing being recorded or only the last file that went through the loop being recorded.
I'll create a portion of the script that looks to see if the log.txt already exists before it tries to create one.

Related

VisualStudioCode debugger says to supply values and gives prompt

I'm trying to use code to get files in a dir and choose the one(s) that are edited in the last 4 hours. For some reason, when I debug this in VisualStudioCode, the debugger says
Supply values for the following parameters:
Process[0]:
$out_path = "C:\Data\Monitor\PropertiesReport\"
#find latest scan file (within 4 hours from now)
$output_sprdsheet_blob_path = Join-Path -Path $out_path -ChildPath "\OutputSprdsht\" #location of scan output file...looks good for path
Get-ChildItem $output_sprdsheet_blob_path -Filter *.xlsx | Foreach-Object
{
$lastupdatetime=$_.LastWriteTime
$nowtime = get-date
if (($nowtime - $lastupdatetime).totalhours -le 4)
{
Write-Host $_.Name
$excel_File_from = $_.Name
#Select-String -Path $_.Name -Pattern "'Execute Time of Send Thread = 60.'"
}
}
#use file found above next
I'm not sure why powershell gives a prompt to supply values foreach-object, when the path is valid for Get-ChildItem. I've used similar code before, and it worked, but I was using PowershellISE, and the code started with the following instead of the Get-ChildItem.
powershell "Set-Location -Path $log_path ; Get-Item *.* | Foreach {...}
I was having the same issue with the above code, where the visual studio code debugger gave the Process[0] prompt and wanted me to supply values at the foreach. This had been tested and used before as well.
I am trying the Get-ChildItem because of the example below doing this, and it looks like it should work. Any idea why the visual studio code debugger gives the prompt and how to fix it?
I have used write-host to print the dir being used, and I pasted the path printed into windows file explorer and there was a file there, and the path was valid.
My powershell version is 5.1.
example get-childitem
Update:
This prints the filename. I'm not sure why it doesn't give the prompt.
$out_pth = "C:\Data\Monitor\PropertiesReport\"
Set-Location -Path $out_pth
Get-Item *.* | foreach-object {write-host $_.name}
Update2:
This prints the filename too:
Get-ChildItem $out_pth | Foreach-Object {write-host $_.name}
It looks like that newline made the difference. This is working:
Get-ChildItem $out_pth | Foreach-Object {$lastupdatetime=$_.LastWriteTime;$nowtime = get-date; if (($nowtime - $lastupdatetime).totalhours -le 40) {$excel_File_from = $_.Name;write-host $_.name}}
write-host "here"
write-host $excel_File_from
prints:
filename.xlsx
here
filename.xlsx
I changed the time from 4 to 40 hours above, because I realized the file was last edited yesterday. But it found the file as well, without the time check on the file properties.

Script to copy files not ending

I have a script that will copy files from a set of folder(s) which match a specific string to a location. The script runs fine for the first server, but on the second it just never ends. I have a write-host step so I know when the first server is done. There are files written from the second server but it never gets to the second write-host command. Any thoughts? [for context the folders I want to search contain "cust+$AppType* and the files are $LogDate_$LogHour.log - these steps work as expected and logs are found and copied for CUST001 server]
Script is below:
$AppType = Read-Host "What App Server do you need calls from? (MCP,RM,SIP,URS,ORS,WFM,WEB,GIR) [can also use * for all servers]"
$LogDate = Read-Host "What date was the call? (yyyymmdd)"
$LogHour = Read-Host "What hour was the call? (hh) [can also use * for entire day]"
$UserName = Read-Host "What is your UserID? (files will be places on Host SAMPLE2\c:\users\*USERID*\Desktop)"
$SrchString = Read-Host "What string are you searching for? (can use connid or ANI for example)"
$LogName = "*"+$LogDate+"_"+$LogHour+"*.log"
$Folder = "*cust"+$AppType+"*"
Get-ChildItem \\customer001\e$\Logs\$Folder -Filter $LogName -Recurse | Select-String $SrchString | Copy-Item -Destination \\SAMPLE2\c$\users\$UserName\Desktop -Force
Write-Host "Finished copying 001 files...."
Get-ChildItem \\customer002\e$\Logs\$Folder -Filter $LogName -Recurse | Select-String $SrchString | Copy-Item -Destination \\SAMPLE2\c$\users\$UserName\Desktop -Force
Write-Host "Finished copying 002 files...."
Exit

How to write progress bar for a script in powershell that finds specific files and deletes them with Get-ChildItem, Remove-Item

I'm new with powershell.
I'm trying to write a script that:
will search in a specific path and delete specific files
write in a log file all files that were deleted and their paths
write in a log file all files that script could not delete, the
reason and their path
progress bar that shows:
*current path that script is working on
*how much time script running
*the amount files that were deleted
*the amount of files that script could not delete
What I've succeeded by now**:
1,2 - log file made after script stops, but i want to be able to check and refresh it to see if new information was added.
here is my code:
#files you want to find, include all in array
$file_names = #('*file1.exe', '*file2.exe', '*file3.exe')
Clear-Host
Write-Host "Hello. A scrip is going to search and delete the following files: $($file_names)." -ForegroundColor Black -BackgroundColor Green
Write-Host "Edit file names in the script if needed." -ForegroundColor Black -BackgroundColor Green
#input the right path were to find a files
$search_path = Read-Host "Please enter the path (for an example: C:\workday\*)"
while(-Not (Test-Path $search_path)){
$search_path = Read-Host "The path $($search_path) is incorrect, please input another one)" }
#path to the log file
Write-Host "The output will be saved to a log file in the disk C:\" -ForegroundColor Black -BackgroundColor Green
$log = "C:\deleted_files_$((get-date).ToString("yyyyMMdd_HHmm")).log"
$log
#search parameters, -recurse: find in subdirectories, -force: grab hidden and system files, SilentlyContinue - continue if there error
try{$search = Get-ChildItem -Path $search_path -include $file_names -Recurse -force -ErrorAction SilentlyContinue | Remove-Item -Force -Verbose 4>&1 | Add-Content $log
$search }
catch [System.UnauthorizedAccessException]{
Write-Warning "Access denied: $search_path"}
Read-Host -Prompt "Press Enter to exit"

Create PS script to find files

I want to start by saying coding is a bit outside of my skill set but because a certain problem keeps appearing at work, I'm trying to automate a solution.
I use the below script to read an input file for a list of name, search the C:\ for those files, then write the path to an output file if any are found.
foreach($line in Get-Content C:\temp\InPutfile.txt) {
if($line -match $regex){
gci -Path "C:\" -recurse -Filter $line -ErrorAction SilentlyContinue |
Out-File -Append c:\temp\ResultsFindFile.txt
}
}
I would like to make two modifications to this. First, to search all drives connected to the computer not just C:\. Next, be able to delete any found files. I'm using the Remove-Item -confirm command but so far can't make it delete the file it just found.

PowerShell - Move file, Rename & Rotate

I am fairly new to powershell and still learning. I have completed my first script and now trying to add some logging into it. I am able to append to log file OK but stuck on backing up the log and rotating it. This is what I have so far
$CheckFile = Test-Path $Logfilepath
IF ($CheckFile -eq $false) {
$Date = (Get-Date).tostring()
$Date + ' - Automonitor log created - INFO' | Out-File -Append -Force $Logfilepath }
Else {
IF ((Get-Item $Logfilepath).length -gt $Size) {
Move-Item $Logfilepath -Destination $LogsOldFolder -Force}
}
This is where I am stuck. If the file is bigger than 5MB I need it to move to another folder (which I have in the script) but when moved into that folder I only want to keep the 5 newest files to avoid storage issues. I will need the files named like the below.
Automonitor.log.1
Automonitor.log.2
Automonitor.log.3
Automonitor.log.4
Automonitor.log.5
Automonitor.log.1 being the newest created file. So I am really baffled on the process I would take and how to rename the files to match the above format and when new file is copied over, to rename all of them again dependent on date created and deleting the oldest so only 5 files ever exist.
I hope that makes sense, if anyone has any ideas that would be great.
You can go this way:
$a = gci $destfolder
if ( $a.count -gt 5)
{
$a | sort lastwritetime | select -first ($a.count - 5) | remove-item
}
This will get you every file older than the first 5.
So, this script doesnt care about the filenames. If you want that, you should Change the $a = gci $destfolder part to some Wildcards.