Invoking Powershell commands in a batch file - powershell

Can anybody help me please in writing the below Powershell commands as a batch file? I will execute the file by command prompt. I don't have the option of creating a ps1 file and executing it through the command prompt.
Thank you.
$limit = (Get-Date).AddDays(-4)
$path = "T:\FolderName"
Get-ChildItem -Path $path -Recurse -Force -include *.txt | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
Get-ChildItem \\123.456.78.910\Y$\Z\*.txt | Where { $_.CreationTime -ge (Get-Date).AddMinutes(-30) } | % { Copy-Item $_.FullName -destination T:\FolderName }

You can invoke powershell.exe with the -command parameter to do this. You can also have more than one powershell command by separating them with semicolon. You should double-double-quote any double-quotes.
Here's an example:
powershell -command "$limit = (Get-Date).AddDays(-4); $path = 'T:\Folder Name';Get-ChildItem -Path $path -Recurse -Force -include *.txt | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force"
powershell -command "$limit = (Get-Date).AddDays(-4); $path = 'T:\Folder Name';Get-ChildItem \\123.456.78.910\Y$\Z\*.txt | Where-Object { $_.CreationTime -ge (Get-Date).AddMinutes(-30) } | % { Copy-Item $_.FullName -destination 'T:\DestinationFolderName' }"
EDIT:
Here is a one-line version of it with only a single set of ""; all quotes inside are single '
powershell -command "$limit = (Get-Date).AddDays(-2); $path = 'D:\Folder\Folder Name'; Get-ChildItem -Path $path -Recurse -Force -include *.txt | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force;Get-ChildItem \\123.456.25.123\D$\folder*.txt | Where-Object { $_.CreationTime -ge (Get-Date).AddMinutes(-30) } | % { Copy-Item $_.FullName -destination 'D:\Folder\Folder' }";

Related

Add timestamp to output log file before each object

I have a powershell script which deletes files and folders older than 180 days, and I would like to add date and time of deletion in the log file before each object. Is that possible?
$limit = (Get-Date).AddDays(-180)
$path = "D:\RAZMJENA DOKUMENATA"
# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Verbose 4>&1 | out-file d:\Delete_script\deleted_files_log.txt -append
# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse -Verbose 4>&1 | out-file d:\Delete_script\deleted_files_log.txt -append
#Delete remaining empty folders older than 180 days.
Get-ChildItem -Path $path -Directory -Recurse | Where {$_.lastwritetime -lt (Get-Date).AddDays($limit) -and (gci $_.fullName).count -eq 0} | Remove-Item -Force -Verbose 4>&1 | out-file d:\Delete_script\deleted_files_log.txt -append
You can do this in you code with add foreachloop
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Verbose 4>&1|foreach{($_.Message).Tostring()+" "+((Get-Date).DateTime).ToString()} | out-file d:\Delete_script\deleted_files_log.txt -append
Yes you can add the current date to every line. For the better understanding I would assign a temporary variable. You can do this with every line of code:
$tmp = Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Verbose 4>&1
$date = Get-Date -Format "MM/dd/yyyy HH:mm" #Format the Date
"$date --> $tmp" | out-file d:\Delete_script\deleted_files_log.txt -append #Append to logfile
Or even better, create a function that you can call everytime you want to log:
function logToFile($tmp){
$date = Get-Date -Format "MM/dd/yyyy HH:mm" #Format the Date
"$date --> $tmp" | out-file d:\Delete_script\deleted_files_log.txt -append
}
Then you can call it whenever you want:
$tmp = Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Verbose 4>&1
logToFile $tmp
If you want to have another format of the date you can get more informations on this page:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date?view=powershell-7

Log deleted files to a text file

I want to know how to log the actions from this script to a text file because I don't know how to do it as the cmdlet Start-Transcript doesn't work for me and I wasn't able to find a solution on the Internet.
The problem is that the Where-Object cmdlet doesn't output anything captured by Get-ChildItem.
Does anybody has a good idea to solve this?
$limit = (Get-Date).AddDays(-30)
$path = Split-Path -Parent $MyInvocation.MyCommand.Definition
Get-ChildItem -Path $path -Recurse -Force | Where-Object {
!$_.PSIsContainer -and
$_.LastWriteTime -lt $limit
} | Remove-Item -Force
Get-ChildItem -Path $path -Recurse -Force | Where-Object {
$_.PSIsContainer -and
(Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object {
!$_.PSIsContainer
}) -eq $null
} | Remove-Item -Force -Recurse
try something like this
$limit = (Get-Date).AddDays(-30)
$path =Split-Path -Parent $MyInvocation.MyCommand.Definition
Get-ChildItem $path -file -recurse -force | where LastWriteTime -lt $limit |
Tee-Object -FilePath "c:\temp\deleted.txt" -Append | Remove-Item
Get-ChildItem $path -directory |
where {(Get-ChildItem $_.FullName -file -Recurse | select -First 1) -eq $null} |
Tee-Object -FilePath "c:\temp\deleted.txt" -Append | Remove-Item
howdy error666,
you can use use a few different methods ...
Tee-Object = fork the stream to a file
-PipelineVariable = accumulate the info in a variable
use a loop = put a log-to-file step in it
put a ForEach-Object in the pipeline
that can both log your info and do the Remove-Item.
the loop is the easiest to understand. [grin] however, if you want to keep it in a pipeline, you could add a ForEach-Object where the Where-Object scriptblock is and put both the filter test and the various actions in that block.
take care,
lee

PowerShell Script only works from PowerShell Console and not from ISE

I am very very new to PowerShell. I am trying to delete a set of Test Results files in folders through PowerShell. When I run the code through PowerShell console, it works. The same code doesn't work through ISE.
Below is the code :
Set-Location -Path "Path";
$testResultsFolder = Get-ChildItem -Include *TestResults -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName;
$date = Get-Date;
$limit = 30;
foreach($testResult in $testResultsFolder)
{
$resultsPath = Get-Item $testResult.FullName;
Get-ChildItem -Path $resultsPath -Recurse -Force | Where-Object { -not $_.PSIsContainer -and $date.Subtract($_.LastWriteTime).Days -gt $limit } | Remove-Item -Force;
}
This works fine from PowerShell console but not from ISE. The ISE does not show any error. It says 'Completed'. Can somebody throw some light on what I am doing wrong?
Try this:
Delete.ps1
#Requires -Version 3
$Path = 'C:\Temp'
$Cleanup = (Get-ChildItem -Path $Path -Include '*TestResults' -Recurse -Directory).FullName
ForEach ($Folder in $Cleanup)
{
Get-ChildItem -Path $Folder -File -Recurse -Force |
Where-Object { $PSItem.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Remove-Item -Force
}
Using Set-Location can result in inconsistent results, especially if you're using dynamic variables. I'd suggest using a variable target so you're getting consistent results.

Powershell delete folders

How can I delete folders, not files, using PowerShell? I want to delete folders that are over 3 days old.
Get-ChildItem "D:\test" |
Where-Object { $_.PSIsContainer -and $_.LastWriteTime -le (Get-Date).AddDays(-3) } |
ForEach-Object { Remove-Item $_ -Force }
This doesn't work. I get no error and it does not delete any folders that are within d:\test.
Try:
Get-ChildItem "D:\test" |
Where-Object { $_.PSIsContainer -and $_.LastWriteTime -le (Get-Date).AddDays(-3) } |
Remove-Item -Force
or:
Get-ChildItem "D:\test" |
Where-Object { $_.PSIsContainer -and $_.LastWriteTime -le (Get-Date).AddDays(-3) } |
ForEach-Object { Remove-Item $_.FullName -Force }
Assuming your using powershell 4+ you don't need to do all the fancy filtering, the -file switch will give you what you need.
Get-ChildItem -Path D:\test -File | Remove-Item
The above will give you what you need.

PowerShell - Get-GhildItem - Ignore specific directory

I am working with a script to clear old files off our file server. We are using this line in the script to find all files older than a certain date:
$oldFiles = Get-ChildItem $oldPath -Recurse | Where-Object { $_.lastwritetime -le $oldDate }
My question is, how do I ignore a certain directory in the $oldPath? For instance, if we had the following:
root
dir1
dir 2
subdir 1
subdir 2
dir 3
subdir 1
dir 4
And we want to ignore dir 2 and all subdirectories when building the list
Final working script:
$oldPath = "\\server\share"
$newDrive = "I:"
$oldDate = Get-Date -Date 1/1/2012
$oldFiles = Get-ChildItem $oldPath -Recurse -File | Where-Object {($_.PSParentPath -notmatch '\\Ignore Directory') -and $_.lastwritetime -le $oldDate }
$oldDirs = Get-ChildItem $oldPath -Recurse | Where-Object {$_.PSIsContainer -and ($_.PSParentPath -notmatch '\\Ignore Directory')} | select-object FullName
$oldDirs = $oldDirs | select -Unique
foreach ($oldDir in $oldDirs) {
$strdir = $newDrive + "\" + ($oldDir | Split-Path -NoQualifier | Out-String).trim().trim("\")
if (!(Test-Path $strdir)) {
Write-Host "$strdir does not exist. Creating directory..."
mkdir $strdir | Out-Null
} # end if
} # end foreach
foreach ($file in $oldFiles) {
$strfile = $newDrive + "\" + ($file.FullName | Split-Path -NoQualifier | Out-String).trim().trim("\")
Write-Host "Moving $file.FullName to $strfile..."
Move-Item $file.FullName -Destination $strfile -Force -WhatIf
} # end foreach
$oldfiles | select pspath | Split-Path -NoQualifier | Out-File "\\nelson\network share\ArchivedFiles.txt"
Modify your Where-Object condition to:
... | Where-Object {($_.PSParentPath -notmatch '\\dir 2') -and ($_.lastWriteTime -le $oldDate)}
Also, you probably want to filter out directory items as well so that $oldFiles contains only files e.g.:
$oldFiles = Get-ChildItem $oldPath -Recurse | Where {!$_.PSIsContainer -and ($_.PSParentPath -notmatch '\\dir 2') -and ($_.lastWriteTime -le $oldDate)}
If you're on PowerShell v3 you can use a new parameter on Get-ChildItem to simplify this to:
$oldFiles = Get-ChildItem $oldPath -Recurse -File | Where {($_.PSParentPath -notmatch '\\dir 2') -and ($_.lastWriteTime -le $oldDate)}
Something like this should work:
$exclude = Join-Path $oldPath 'dir 2'
$oldFiles = Get-ChildItem $oldPath -Recurse | ? {
-not $_.PSIsContainer -and
$_.FullName -notlike "$exclude\*" -and
$_.LastWriteTime -le $oldDate
}
Try $oldFiles = Get-ChildItem $oldPath -Recurse -Exclude "dir 2" | Where-Object { $_.lastwritetime -le $oldDate}