I'm trying to write a powershell script that will create outlook logs (using NETMON) from the local client to the exchange server. The problem is the file name is not incrementing correctly. I found this incrementing script online and i understand the logic (kinda). Am i using the right way to initialize the counter? It isn't renaming the file correctly. It gives the 2nd file just a _ then the 3rd file gets a _2 then after that it stops renaming files.
ALSO is invoke-expression waiting for my cmd to exit or will it just go to the next step of $count-- ?
#Directory to complete script in
$path = "c:\Outlook_Logs\"
cd $path
$cmdline = "Nmcap.exe /network * /captureipv4.address==X.X.X.X /file :\outlook_logs\client_$count.chn:100MB"
#Writes out number of files in directory to console
$count = (get-childitem $path -name).count
Write-Host "Number of Files: $count"
#Sorts items by decsending order
$items = Get-ChildItem | Sort Extension -desc
#Deletes oldest file by file extension number
del $items[0]
#Copy file from original directory to backup directory
Copy-Item c:\Outlook_Logs\* c:\Outlook_Logs_Temp\
#Sorts items by decsending order
$items = Get-ChildItem | Sort Extension -desc
#Renames files in quotes after NewName argument
$items | ForEach-Object -begin { $count= (get-childitem $path -name).count } -process { rename- item $_ -NewName "client_$count.cap";Invoke-Expression "$cmdline"; $count-- }
There's no need to increment the names yourself. chn captures files are created and names incrementally automatically when they reach the size specified after the colon.
What happens when you lower the size to 1MB and execute the command?
Related
All my movies has a separate folder with a single video file in it. I want all files in a single folder. Accept for the ones with multiple parts (eg. tv series)
I have this powershell script that when $commit=false verboses all the filenames nicely in the list but does not execute the move and delete. I cannot get it to work.
Move videofile from subDir to parentDir
Delete subDir
$commit = $true
$extensions = '.mp4','.avi','.mpg','.mpeg','.mkv','.3gp','.wmv'
$path = 'L:\My Drive\Film\Test'
$folders = gci $path -Directory
foreach($fo in $folders) {
$file = #($fo | gci -File | ? { $_.Extension -in $extensions })
if($file.Count -eq 1)
{
if($commit)
{
[void](mi -Path $file.FullName "$($fo.Parent.FullName)\$($file.Name)")
[void](ri -Path $fo.FullName -Recurse)
}
else
{
Write-Host "$(Get-Date) | Moving '$($file.FullName)' to '$($fo.Parent.FullName)' and deleting folder '$($fo.FullName)'"
}
}
}
Copying the documentation for the next reader since the issue was in path vs literalpath.
https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/supporting-wildcard-characters-in-cmdlet-parameters?view=powershell-7.1
Many Windows PowerShell cmdlets support wildcard characters for their
parameter values. For example, almost every cmdlet that has a Name or
Path parameter supports wildcard characters for these parameters.
(Although most cmdlets that have a Path parameter also have a
LiteralPath parameter that does not support wildcard characters.) The
following command shows how a wildcard character is used to return all
the cmdlets in the current session whose name contains the Get verb.
...
Supported Wildcard Characters * ? [ ]
I'm trying to automate renaming of many multiple files in a Windows 7 directory. I need to search a source index file (.txt or .csv which is a list of extended file names) and, where there is a partial match to the original file name, copy the first 12 characters (of the relevant string in the index file) and rename the original file accordingly (and preserving original file extension).
e.g.
(a) Files currently in the Windows directory are named as follows (hundreds of files):
23456abc.doc
76543cab.doc
92837bca.doc
(b) Values in the .txt/.csv file as follows (hundreds of values - NOTE: these do not have file extensions):
BetterName1.RandomText1.23456abc.MoreRandomText1
BetterName2.RandomText2.76543cab.MoreRandomText2
BetterName3.RandomText3.92837bca.MoreRandomText3
(c) Desired Result is for the files to be auto renamed as follows:
[by searching for filename in (a) within the list of values in (b) and, where there is a match, returning the first 12 characters as the new filename whilst preserving the original file extension]
BetterName1.doc
BetterName2.doc
BetterName3.doc
NOTE: My preference is to use an Index file for the look-up that is in .txt format. However in need I can also use a .csv
I have never used PowerShell before and am new to Windows batch scripting. I have searched around and tried to cobble together snippets of code into a Windows batch script (also tried a PowerShell script) to achieve this but my knowledge in this area is seriously lacking so unfortunately I'm still struggling away at square one.
Any assistance would be greatly appreciated. Thank you in advance.
P.S. Here is a PowerShell script that I tried to get working but to no avail.
$fdPath = 'C:\TEST\Data'
$sourcelistFiles = Get-ChildItem -Path $FDPATH\*.txt | ForEach-Object {$_.user } FullName
$findReplaceList = Import-Csv -Path $FDPATH\AllNames.csv
$totalitems = $sourcelistFiles.count
$currentrow = 0
foreach ($sourcelistFile in $sourcelistFiles)
{
$currentrow += 1
Write-Progress -Activity "Processing record $currentrow of $totalitems" -Status "Progress:" -PercentComplete (($currentrow / $totalitems) * 100)
[string] $txtSourceListFile = Get-Content $sourcelistFile | Out-String
ForEach ($findReplaceItem in $findReplaceList)
{
$txtSourceListFile = $txtSourceListFile -replace "$($findReplaceitem.FindString)", "$($findReplaceitem.ReplaceString)"
}
$txtSourceListFile | Set-Content ($sourcelistFile)
-NoNewLine
}
$FDPATH = 'C:\TEST\Data'
foreach($obj in (Import-Csv -Path $FDPATH\AllNames.csv)){
foreach($thing in $(gci -Path $FDPATH\*.txt)){
if("123.hash.avocado" -match $thing.basename){$ret = $thing.fullname}
}
$stuff = $obj -split "."
ren -Path $ret -NewName $stuff[0]
}
See if this works, it iterates through the csv then iterates through the directory to see if the directory's name is in the csv's line that is being iterated, then sets a variable to be the fullname of the file and renames it to the first name before the period.
Import-CSV LISTA.csv -Header newFileName | % { Copy-Item -Path archivo_convert.pdf -Destination "$($_.newfilename).pdf" }
I have a few thousand files where the author name is contained in the filename of the file. The main problem this creates is that the filename becomes too long as all authors are mentioned and moving them to different folders becomes impossible to due windows filename length limit. I need to rename the files by removing everything after the last occurance of "by " including the "by " itself.
The only way to rename so many files is to write a program of some sort. What would be the quickest way to do this?
You can use a PowerShell script to rename multiple files.
Give this a try:
$cur_dir = pwd
$files = Get-ChildItem $cur_dir
foreach($file in $files){
$rev_name = $file.name
$rev_name = $rev_name.ToCharArray()
[Array]::Reverse($rev_name)
$rev_name = -join $rev_name
$indi = $rev_name.IndexOf("yb")
if($indi -ge 0){
$start_ind = $rev_name.length - $indi-2
$final_name = $file.name.substring(0,$start_ind)
Rename-Item -Path $file.name -NewName $final_name
}
}
I hope it helps.
i am trying to loop through all files no matter the type, in a folder, and change a string with one that is input by the user..
i can do this now, with the code below, but only with one type of file extension..
This is my code:
$NewString = Read-Host -Prompt 'Input New Name Please'
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$InputFiles = Get-Item "$scriptPath\*.md"
$OldString = 'SolutionName'
$InputFiles | ForEach {
(Get-Content -Path $_.FullName).Replace($OldString,$NewString) | Set-Content -Path $_.FullName
}
echo 'Complete'
How do i loop through the files, no matter the extension ?
so no matter if it is a md, txt or cshtml or some other, it will replace the string as instructed.
To get all the files in a folder you can get use Get-ChildItem. Add the -Recurse switch to also include files inside of sub-folders.
E.g. you could rewrite your script like this
$path = 'c:\tmp\test'
$NewString = Read-Host -Prompt 'Input New Name Please'
$OldString = 'SolutionName'
Get-ChildItem -Path $path | where {!$_.PsIsContainer} | foreach { (Get-Content $_).Replace($OldString,$NewString) | Set-Content -Path $_.FullName }
this will first get all the files from inside the folder defined in $path, then replace the value given in $OldString with what the user entered in when prompted and finally save the files.
Note: the scripts doesn't make any difference regarding if the content of the files changed or not. This will cause all files modified date to get updated. If this information is important to you then you need to add a check to see if the files contains the $OldString before changing them and saving.
I have never used Powershell (or VBScript) as I am new to IT-Admin and would appreciate some guidance with renaming files.
On a daily basis, I will be downloading files useing Filezilla manually from a SFTP connection to a local directory filder called YYYYMMDD (although later, I will want to write an automated task that does this form me on a scheduled basis). What I would like to set up is some kind of task that when the files land into the distination directory, they get renamed.
For today's download, I have the following files that I would like to rename:
Original Name Renamed Filename
wcm14444.csv.11.10.20_09.32 wcm14444_111020_0932.csv
wcm14444.csv.11.10.21_00.09 wcm14444_111021_0009.csv
wcm14444.pdf.11.10.20_09.32 wcm14444_111020_0932.pdf
wcm14444.pdf.11.10.21_00.10 wcm14444_111021_0010.pdf
wcm1cash.csv.11.10.21_00.56 wcm1cash_111021_0056.csv
wcm1money.csv.11.10.21_00.56 wcm1money_111021_0056.csv
wcm1opnpos.csv.11.10.21_00.56 wcm1opnpos_111021_0056.csv
wcm1trades.csv.11.10.21_00.56 wcm1trades_111021_0056.csv
wcm1_an.pdf.11.10.21_03.26 wcm1_an_111021_0326.pdf
wcm1_ds.pdf.11.10.21_00.22 wcm1_ds_111021_0022.pdf
wcm1_ep.csv.11.10.21_03.26 wcm1_ep_111021_0326.csv
wcm1_ms.pdf.11.10.21_03.26 wcm1_ms_111021_0326.pdf
You will notice in my renaming requirement:
1. The file extension appears in the middle of the filename and gets placed to the end.
2. I am replacing "." with "" where they appear as date seperators. If its of any help, I am only expecting to receive file types of (".csv", ".pdf" , ".xls") and where these appear within the filename, they get replaced with "_".
Currently I would use Excel to perform the task, but this seems quite hard to deploy as a system task? This seems more of a task for Powershell.
If I am creating YYYYMMDD folders for example N:\SFTP\Provider1\YYYYMMDD, what would be the best way of automating the renaming of the files as the files are downloaded into each day's YYYYMMDD (noting that on same days there may not be a folder created because there are no new files).
Many thanks and kind regards,
Bertie.
Thanks all for the help. More for the benefit of those stumbling accross this page. I have now created a Rename_SFTP.ps1 file at N:\SFTP\Provider1\ containing
$pattern = '^([^\.]+)\.(csv|xls|pdf)\.(\d{2})\.(\d{2})\.(\d{2})_(\d{2})\.(\d{2})'
$todayDate = Get-Date -Format "yyyyMMdd"
Get-ChildItem (".\" + $todayDate + "\") -Recurse | Foreach-Object{
if($_.Name -match $pattern)
{
echo $NewName
$NewName = "{0}_{1}{2}{3}_{4}{5}.{6}" -f $matches[1],$matches[3],$matches[4],$matches[5],$matches[6],$matches[7],$matches[2]
Rename-Item (".\" + $todayDate + "\" + $_) -NewName $NewName
}
}
I have then created a RunRenameTaskForToday.bat containing
powershell .\Rename_SFTP.ps1
At least this way, when I download the files manually, all I need to do is double click on a .bat file one level higher up and it will figure the right folder that needs the files to be renamed. All I need to do know is figure out a way to downlaod the SFTP stuff autonatically...
Thanks all.
Quite a complex task here, with several problems (and, most probably several solutions). Here are some guidelines to get you going:
Use Get-ChildItem | Foreach-Item to traverse all files. The $_ holds the current item.
Powershell has very good support for regular expressions, use if ($_ -match "regexp"). I tend to name the matches, to easier identify them. Something like this could work for your specific naming format:
if ($s -match "(?<pre>.*)\.(?<ext>csv|pdf)(?<date>.*)_(?<hour>\d{2})\.(?<min>\d{2})") {
$newname = $matches["pre"] + "_" +
($matches["date"] -replace "\.","") +
"_" + $matches["hour"] + $matches["min"] +
'.' + $matches["ext"]
}
To get the current day, use Get-Date -Format "yyyyMMdd". Use that to create a new folder each day.
Here's another way using a format string to create the new name. Each group of pattern characters surrounded in parenthesis denotes a part of the file name to be captured and is used later on in the $NewName to form the new file name:
$pattern = '^([^\.]+)\.(csv|xls|pdf)\.(\d{2})\.(\d{2})\.(\d{2})_(\d{2})\.(\d{2})'
Get-ChildItem D:\temp -Recurse | Foreach-Object{
if($_.Name -match $pattern)
{
$NewName = "{0}_{1}{2}{3}_{4}{5}.{6}" -f $matches[1],$matches[3],$matches[4],$matches[5],$matches[6],$matches[7],$matches[2]
Rename-Item $_ -NewName $NewName
}
}
Well quickly something called bricolage ...
$ext = ("csv", "pdf", "xls")
foreach ($e in $ext)
{
Get-ChildItem "*$e*" | % {$newName = $_.name.replace('.',''); $newName;
Rename-Item $_.fullname -NewName ($newName -replace "(.*)($e)(.*)",'$1_$3.$2')}
}