copy-item powershell issue - directory-structure

This may be a very ridiculous question but when executing the copy-item command, only the main folder is copied MINUS the contents within. for example I have
\server1\parent\child <<---this folder has items nested within but copy-item only moves the folder, not the items within. I have tried the following 2:
copy-item "\\server1\parent\child -destination "\\server2\parent\child
copy-item "\\server1\parent\child\* -destination "\\server2\parent\child
but again, the first line only moves the folder and the second lines moves folder and items but items are not moved within the folder. I was wanting to keep the folder structure the same as from where I am copying it from. I looked at a few places, including here, and I must be missing something.
Any help would be awesome!

I found the answer right after I posted the question. I was missing the -recurse option after the \server1\parent\child. The line that now works is
copy-item ''\\Server1\parent\child" -recurse -destination "\\Server1\parent\child"
Thanks Everyone!

Related

PowerShell 5 (now updated to 7) - Check if multiple levels / depths of subfolders exists and if so move its contents up one level

Normally I wouldn't even post without some framework together, but I'm stumped on where to begin.
I have a directory of hundreds of subfolders that should only be one level deep but some are two levels deep:
C:\MainDirectory\SubfolderA\
C:\MainDirectory\SubfolderB\
C:\MainDirectory\SubfolderC\
C:\MainDirectory\SubfolderC\SubfolderC1\
I need to recursively go through the MainDirectory, and if there's a second sublevel of files, then move just those files up one level (so that SubfolderC1's files are actually placed in SubfolderC) and then those files need to have SubFolderC1's name appended to the front of the file.
Ex:
C:\MainDirectory\SubfolderC\SubfolderC1\FileA.type
would become:
C:\MainDirectory\SubfolderC\SubfolderC1FileA.type
I don't know the subfolders or filenames ahead of time, they could be named anything.
The following feels like a start.
$source = "C:\MainDirectory"
$levels = Get-ChildItem $source -Directory -Recurse | ForEach-Object {$_.PSPath.Split('\').Count}
if ($levels -gt 3) {
}
But I don't know how to use the results for anything meaningful.

remove some character string from multiple filenames

my OS is Win 10. i have a folder which contains files like: '1.JPG.JPG.jpg' or '99.JPG.jpg' or '335.JPG.JPG.jpg' -almost 470 files-
notice that the file names are look like value of ID column to reference and some files have 2 times '.JPG' but some have 1 time. also there are some files contains 'jpg' instead of 'JPG' (both without quotes) in between file name.
i want to rename all files with number value in start of file name and then add .jpg to all files like 1.jpg or 99.jpg or 335.jpg etc. this is sure all files are jpeg, there is no .png or .bmp etc.
please help how i can do this?
EDIT: can i used to get digit part of file name and hard code .jpg and replace all file names at once using script, if yes, please guide how it can be done?
its done using following Powershell commands searched from internet:
step 1) ls | Rename-Item -NewName {$_.name -replace ".JPG.JPG",""}
step 2) ls | Rename-Item -NewName { [io.path]::ChangeExtension($_.name, "jpg") }
hope peoples like me (the novice) will get benefit.
Link: https://www.windowscentral.com/how-rename-multiple-files-bulk-windows-10#:~:text=You%20can%20press%20and%20hold,file%20to%20select%20a%20group.

How do I match a filename without quotes to a name with quotes?

If somebody knows a better title, please do tell me.
Given these examples:
Three files called: Jacobs.Ladder.txt, Emma.Unplugged.2020.txt & Emma.txt
Three folders called: Jacobs.Ladder.2019, Emma.Unplugged & Emma
Three database-entries called: Jacob's Ladder, Emma: Unplugged & Emma
My PowerShell script is presented with the file, then needs to find the right folder, copy it there, then find the entry in the database and update it there. I need a script that catches all three cases.
So far, what I've done is this:
I take the file's BaseName property:
Jacobs.Ladder, Emma.Unplugged, Emma
I use Get-ChildItem to put all directories in a variable, do:
$Directories | Where-Object -Property 'Name' -Contains $File.BaseName
This finds exact matches, so it will only find the folder Emma
Next, if nothing was found, I do:
$Directories | Where-Object -Property 'Name' -Like ('{0}*' -f $File.BaseName)
This finds the folder Jacobs.Ladder.2019. It has already found Emma in the previous step, so that has been handled. It will not however, find Emma.Unplugged because the file's BaseName is Emma.Unplugged.2020.
So that's my first challenge/question: how do I write a conditional that matches Emma.Unplugged.2020 to Emma.Unplugged?
Next, to match the file name with the database entries, I start with a replace to turn the dots into spaces.
I then search for an almost exact match:
$Database | Where-Object -Property 'Name' -Like $FileNameWithSpaces.Replace(' ','*')
I know, I could have just replaced the dots with asterisks. But I don't know yet if the name with spaces is going to be useful somewhere else.
Although this does compensate for the colon in Emma.Unplugged, this once again only finds Emma.
There is my second challenge: how do I form my query to match (again) Emma.Unplugged.2020 to Emma: Unplugged but also Jacobs.Ladder to Jacob's Ladder?
Of course, if you can think of more scenarios that I didn't catch here, feel free to add those in your code.
As for the topic title, my biggest challenge is that single quote in the word. Right now the best way I can think of is if I on-the-fly turn all database-names into their filename equivalent. Then Jacob's Ladder would become Jacobs.Ladder and I would have a match. Which would leave the 2020 as my biggest challenge.

Check if string is like regex

I have a folder of many applications that are used for deployment on laptops or workstations. Now this folder is becoming a big mess because multiple people use this folder and everyone uses a different storage method. Therefore I wanted to write a script that helps manage the files in a way we can always find them.
In Powershell I want to.
List all the files (.msi, .exe, and maybe more)
Determine if the files are correctly stored already (Developer\Application\Application_version_architecture.extension ie. Adobe\Flashplayer\Flashplayer_22_x64.msi)
If true, leave it.
If not, I question the user of the script
some things about the application so the script then renames and
moves it to the correct folder.
Currently I'm stuck on step 2. I want to use a regex where I determine what the standard should be. However, it keeps ruling out applications that are correctly named.
I use the following command to retrieve the filenames:
Get-ChildItem -Path $path -Recurse -Name
This retrieves the files in the application folder with complete path like
"Adobe\Flashplayer\Flashplayer_22_x64.msi"
Or when incorrect
"Adobe\flashplayeractivex.msi"
I then use the following regex to check if they are correct or incorrect
\w*\\\w*\\[a-zA-Z]*\_[0-9a-zA-Z\.]*\_(([x][6][4])|([x][8][6])|([b|B][o][t][h]))\.(([m|M][s|S][i|I])|([e|E][x|X][e|E]))
Which I have confirmed working on Rubular.
However, I cannot get it working with powershell. I've tried the following:
if ($file -match '\w*\\\w*\\[a-zA-Z]*\_[0-9a-zA-Z\.]*\_(([x][6][4])|([x][8][6])|([b|B][o][t][h]))\.(([m|M][s|S][i|I])|([e|E][x|X][e|E]))') {......commands...}
Which does not seem to work because of the escapes (Powershell threw some errors at me). I then tried:
$pattern = [regex]::Escape('\w*\\\w*\\[a-zA-Z]*\_[0-9a-zA-Z\.]*\_(([x][6][4])|([x][8][6])|([b|B][o][t][h]))\.(([m|M][s|S][i|I])|([e|E][x|X][e|E]))')
if ($file -match $pattern) {......commands...}
Which didn't gave me errors, but did not work because it didn't "match" "Apple\iTunes\iTunes_12.3_x64.exe" which does match on Rubular.
Does anyone recognize this problem or see what I do wrong?
I wouldn't try all this in a single regex. Instead I would check each policy individually:
$path = 'C:\tmp'
$validExtensions = #('.msi', '.exe')
$filnameRegex = '\w+_[0-9a-zA-Z\.]+_(?:x32|x64|[b|B]oth)'
Get-ChildItem -Path $path -Recurse | ForEach-Object {
if (-not ($_.Extension -cin $validExtensions))
{
Write-Host "$($_.FullName) has an invalid extension."
}
if (-not ($_.BaseName -match $filnameRegex))
{
Write-Host "$($_.FullName) doesn't match the filename policy."
}
if (3 -ne ($_.FullName.Split([System.IO.Path]::DirectorySeparatorChar).Length `
- $path.Split([System.IO.Path]::DirectorySeparatorChar).Length))
{
Write-Host "$($_.FullName) doesn't match the directory policy."
}
}

regex help for replacing directories under certain conditions

I need to write a regex to update some registry files for work for an upcoming migration
I have to dynamically update all strings in files where:
has a directory path that starts with C:
directory does not have "xyz" or "abc" in the path
if the string in the file contains a file [EX *.ext], the only thing that is updated is the directory path and not the filename & extension so those are left alone
does not replace but instead keeps any appending information in the string [EX: " " " or ")"] that are used to close out the string parameters in the files
I have got it doing 1 and 2, but not 3 and 4. I'm using PowerShell 4.0, recursively checking files in a directory and producing a new file with the changes for each file found in each subdirectory.
The conversion should look like:
FROM: setting1="\"C:\\\\this\\\\is\\\\\adirectory\""
TO: setting1="\"O:\\\\\New_Directory_Path\""
FROM: othersetting="\"C:\\\\this\\\\abc\\\\directory""
TO: UNCHANGED
FROM: thisfile="\"(C:\\\\this\\\\directory\\\\somefile.some_ext)""
TO: thisfile="\"(O:\\\\New_Directory_Path\\\\somefile.some_ext)""
I'm at my wits end on this one, this is what I have so far, in terms of regex:
gc $file | % {$_ -replace "C:(?!.*abc.*)(?!.*xyz.*)(?!.*\..*).*","O:\\\\New_Directory_Path\"} | out-file "$filePath\$newFileName"
Hoping someone on here can lend a hand. Also, this is my first time posting on here, sorry for not putting my code in tags.
try this pattern
Edited:
C:(?!.*(abc|xyz)).*?(?=[^\\]+\.[^\\]+|$)
Demo