Using Powershell to select only one file in a folder - arrays

I've been trying to figure out a way to use Powershell to select only one file (doesn't matter which one) out of a folder so I can do a rename on it. After that I want it to just exit. Please be patient with me, I'm new to PS, most of my coding experience is in other languages.
So I've been doing something like this so it just executes once and exits...
$a = 0
DO
{
$a
$a++
} While ($a -le 0)
Would I put a Get-ChildItem in there somehow, or how do I reference the file so I can rename it to something like "newfile.txt"? Plus the file location is not local on my machine, it's on a UNC path so not sure how to point it to another location.
Thanks in advance.

Try this:
Get-ChildItem "\\Server\path" -file | select -first 1 | Rename-Item -NewName "newname.txt"

Related

Powershell ISE - How do I copy many files and rename them at the same time?

I'm trying to use Powershell ISE to help me do the following:
Perform a search for many files (with an extension of *props.tmpl) under a certain folder and to include all sub-directories.
When found, I want to copy that file to its current location, but with an extension of *.tmpl2 (what I really want is to skip this step and copy *props.tmpl to a file called *props)
Then rename all *.tmpl2 files and remove the tmpl2 entirely, leaving just the *.props extension.
Ideally, what I want is to copy existing files to the same directory with a new name. It seems like all of the searches I've ran on Powershell ISE are not coming up with the right info I need (or I'm not searching for the right way to do it - trying 'powershell ise copy many files with new names' didn't help.
I had the replacement piece down and working, but I no longer want to eliminate the original tmpl files (they are templates so I may want to review them later for their original content).
What I was doing to replace them was this:
Get-ChildItem -Filter "*props.tmpl" -Recurse |
Rename-Item -NewName { $_.name -replace '.tmpl',''}
Which works great other than completely removing the original file.
I started trying to piece something together, but I'm not understanding how to properly name the copy and stopped at this point with just an error (this was an attempt to skip the extra copy and just simply rename the copy instead of adding the extra step of '*.tmpl2'):
# Get all *props.tmpl files
Get-ChildItem -Filter "*props.tmpl" -Recurse |
# Iterate through each found file
ForEach-Object {
Copy-Item $_.name |
Rename-Item -NewName { $_.name -replace '.props.tmpl','.props' }
}
Any help would be really appreciated (not much of a Powershell guy, but I'm trying to learn since powershell tends to be a little more dynamic then oldschool batch scripts).
Thanks in advance
Final version of this script per help from #ssennett
Here's my final version:
# Get all *props.tmpl files
Get-ChildItem -Filter "*props.tmpl" -Recurse |
# Iterate through each found file and copy it to non-template form in same location
ForEach-Object {
Copy-Item $_.FullName ($_.Name -replace '.tmpl','')
}
You're not too far from the answer! It's just how Copy-Item is being handled.
Without a Destination being specified, the Copy-Item will effectively try and copy the file onto itself. Instead of piping it to Rename-Item, you can handle the renaming with the -Destination parameter, as below.
$files = Get-ChildItem -Filter "*props.tmpl" -Recurse
$files | % { Copy-Item -Path $_.FullName -Destination ($_.Name -replace 'props.tmpl','.props') }
This would copy a file called RandomFileprops.tmpl into another file RandomFile.props. If you want to remove the original, you can use the Move-Item cmdlet with the same parameters, which effectively renames the original file.

Powershell Match Filename with same basename but different file extensions and copy them to another folder

Powershell Version 2
Need some power shell help, Got a directory like the example below. Where there will be lots of files , the common property of them will be the name but with different extensions. I need to to recurse through the directory match any with the same base name and copy them to a location. The files need to be copied to the destination together.
Example of files. 40127.wav , 40127.txt , 40127.ini , 40128.wav , 40128.txt , 40128.ini
My example script Works but for only one member of the array. As i call the member of the array using $test[0] to match the basename. Not sure how to get it to go through the array as i seem to be breaking the foreach command.
$source = c:\audio
$test = Get-ChildItem -Path $source
foreach ($item in $test)
{get-childitem -path $source -recurse | where {$_.basename -eq $test[0].basename } | Move-Item -Destination C:\Backup }
Result
3 files in C:\backup 40127.wav , 40127.txt , 40127.ini .
Any help much appreciated.

Optimizing Powershell Script to find old files and delete them on DFS replicated folders

Here is the story. I have a fileshare that is replicated between 2 servers located in different places in the world. DFS will not replicate a file if it has only been viewed, but I wouldn't want to delete that file/folder because it was used within the time period I have set (7 days). So to make sure that I don't remove still used files I have to check both locations for their LastAccessTime.
I currently have this
Set-ExecutionPolicy RemoteSigned
$limit = (Get-Date).AddDays(-7)
$PathOne = "FirstPath"
$PathTwo = "SecondPath"
$ToBeDeletedPathOne = Get-ChildItem -Path $PathOne -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.LastAccessTime -lt $limit }
$TobeDeletedPathTwo = Get-ChildItem -Path $PathTwo -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.LastAccessTime -lt $limit }
$DiffObjects = Compare-Object -referenceobject $ToBeDeletedPathOne -differenceobject $ToBeDeletedPathTwo -IncludeEqual
$ToBeDeletedOverall = DiffObjects | where {$_.SideIndicator -eq "=="}
After this, I loop through and delete the files that are marked for deletion by both locations.
Part of the problem I have is that there are a tremendous amount of files and this can take a very long time. So I wanted to make it better/faster. My idea is to have this script run the scan as a different script on each FS server and wait for them to return the output. That way it can scan on the local machine easier than remotely and it would scan both locations simultaneously.
The other part of the problem comes in with the fact that I have no idea how to do this. I will continue to work on this and if I solve it, I will post here in case anyone in the future finds this useful.
You could run everything locally. Copy the script to the machines you want (make a script to copy them if you need to) then use something like PSTools to kick them off on the local machines. This should essentially run the script simultaneously on all machines.

Script to recursively remove specific file from child paths?

I've tried searching for this answer for awhile now, but can't seem to find what I'm after. Perhaps I'm wording it strangely.
I need a script that will recursively delete a specific file from each child directory in a network share.
For example:
\\\share\\*\a\b\file.settings
The * represents n number of child directories. The rest of the path will always be the same. It seems like I might be able to do this with a combination of Get-childitem and remove-item in Powershell, but I'm having trouble working out the exact command I need.
Any help would be immensely appreciated! Thanks.
Something like this should work:
Get-ChildItem '\\server\share' -Recurse | ? {
$_.FullName -like '*\a\b\file.settings'
} | Remove-Item
If you're just interested in files .\a\b\file.settings in the immediate child folders of \\server\share you could simplify the code to something like this:
Get-ChildItem '\\server\share\*\a\b\file.settings' | Remove-Item
Breaking out my comment code into long form:
$folders = Get-ChildItem "\\server\share\" -Directory
ForEach ($folder in $folders) {
$file = Join-Path $folder.FullName "\a\b\file.settings"
if (Test-Path $file) { Remove-Item $file }
}
While I wasn't able to get this to work with Powershell, the below VBS I put together does seem to work well:
Set FSfolder = FSO.GetFolder(\\server\share)
For Each subfolder In FSfolder.SubFolders
UserProfile=subfolder.Name
SettingFile="\\server\share\" & UserProfile & "\a\b\file.settings"
If FSO.FileExists(SettingFile) Then
FSO.DeleteFile(SettingFile)
End If
Next

Rename files using results of Get-ChildItem in powershell

I have looked for questions relating to my issue, but can't find the correct syntax to use for what I want to achieve.
I want to take all the filenames from a folder using Get-ChildItem, and store these in a variable, then rename all the files in another folder using these names.
From what I have seen, I need something similar to:
CD directory a
$newnames = Get-ChildItem
CD directory b
Get-ChildItem | Foreach {$name = $newnames} | Rename-Item -Newname {$name}
I think perhaps the issue I am facing, is calling the name correctly from the $newnames variable.
Can anyone advise the correct syntax for what I need to do?
Here's one way assuming you have the same count of files in those folders. Remove the -WhatIf switch to actually rename the files:
[array]$a = Get-ChildItem .\DirA
[array]$b = Get-ChildItem .\DirB
for($i=0; $i -lt $a.Length; $i++)
{
$b[$i] | Rename-Item -NewName $a[$i] -WhatIf
}

Resources