backing up certain files in a folder using powershell - powershell

I have a couple of questions. I have certain binaries in a folder...
F:\program files\application\Client\
I only want to copy the latest dll's that have a certain phrase in there names. Lets say "MVCsite". I know you can use Get-ChildItem -Filter with the filter parameters, to get just child items with a .dll extension, but is there a way to look for specific files with specific keywords, or am I going to have to literally copy a list of files out of the directory and move it to a back up folder? Is there a quick and dirty command to do that? As you can tell, I am new to powershell, but I am learning fast.

gci -path $path -filter "*.dll" | where {$_.Name -match "Keyword1|Keyword2|etc"}

Simply use wildcards in your -Path parameter:
Copy-Item F:\program files\application\Client\*MVCsite*.dll X:\DestinationDir
That will copy all files in F:\program files\application\Client\ whose names contain the string "MVCsite" and have the extension ".dll". Is that what you wanted to accomplish? If not, please clarify.

Related

Powershell Script to find a specific file type in specific subfolders of a directory

I have a directory with several subfolders in it. I specifically want to search for the directory for a set of subfolders that begin with the combination "SS". Once it finds those specific subfolders, I want to run a batch file on those folders and also delete files of specific file type.
I've got the search for the specific subfolders to work using gci and -Recurse using the following code:
$BaseDir = "P:\Directory1\"
$FolderName = "SS"
Get-ChildItem $BaseDir -Recurse | Where-Object {$_.PSIsContainer -and $_.Name.StartsWith($FolderName)}
This finds the correct subfolders, but I'm lost on how after I've gotten these results to run the batch file on them and delete the files with the specific file type. I've tried using foreach and ForEach-Object, but it's not giving any results. I've searched and can't seem to find a solution for this.
You could also use -Include, but it's picky about the path handed to it.
get-childitem( join-path $directory "*") -Include *.txt,*.pdf
The -Include option needs the path to have that trailing * wildcard on it, and WILL NOT work without it.
join-path is also the OS-safe way to create a path without using a directory delimiter that might not work if you're running the code on a non-Windows host.

Powershell: How to copy files from one Directory to another

I am looking to copy a series of files from one directory to another. Essentially the files are a series of zip folders that are simply changed versions of programs. The files will be named something like: test_1_092.zip in the source directory and test_1_091.zip in the target directory. I don't want the script to look at the numeric portion of the folder, simply the name.
Please forgive my lack of knowledge as this is my first foray into powershell scripting. Any thoughts or need more info?
Something to start with
(Get-ChildItem -Filter "*.zip").Name | where {$_ -like 'test_1_*'} | Move-Item -Destination .\1 -Force -WhatIf
Please confirm the output from –whatif , then remove it to perform the action.
For the relation between the new and old name, please provide some more information.

Apply setCaseSensitiveInfo recursively to all folders and subfolders

I am trying to configure my dotnet core project (in Windows) as "case sensitive", so it behaves as in my production server (linux).
I have found this way of doing it:
fsutil.exe file setCaseSensitiveInfo "C:\my folder" enable
The problem is that this function is not recursive:
The case sensitivity flag only affects the specific folder to which you apply it. It isn’t automatically inherited by that folder’s subfolders.
So I am trying to build a powershell script that applies this to all folders and subfolders, recursively.
I have tried googling something similar and just modifying the command line, but I don't seem to find the corrent keywords. This is the closest that I've gotten to this sort of example.
Correct code:
(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {fsutil.exe file setCaseSensitiveInfo $_ enable}
Explanation:
NOTE: The code in the answer assumes you're in the root of the directory tree and you want to run fsutil.exe against all the folders inside, as it's been pointed out in the comments (thanks #Abhishek Anand!)
Get-ChildItem -Recurse -Directory will give you list of all folders (recursively).
As you want to pass their full path, you can access it by using .FullName[1] (or more self-explanatory | Select-Object -ExpandProperty FullName ).
Then you use ForEach-Object to run fsutil.exe multiple times. Current file's FullName can be accessed using $_ (this represents current object in ForEach-Object)[2].
Hint:
If you want more tracking of what's currently being processed you can add the following to write the path of currently processed file to the console: ; Write-Host $_ (semicolon ; is to separate from fsutil invocation) as it was pointed out in the comments (thanks Fund Monica's Lawsuit !)
[1] .FullName notation works for PowerShell 3.0 and greater, Select-Object -ExpandProperty FullName is preferred if there's a chance that lower version will be used.
[2] $_ is an alias for $PSItem
(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {if (-Not ($_ -like '*node_modules*')) { fsutil.exe file setCaseSensitiveInfo $_ enable } }
I modified #robdy's code to allow excluding node_modules. You can replace the "node_modules" bit in the above with anything to exclude filepaths containing it.
If you're working with npm, you probably want to exclude node_modules. #robdy's answer is great, but was taking minutes at a time iterating over every single node package folder even if I didn't have the package installed; given that this is something one might want to run fairly often since directories might be added all the time, and since you probably aren't modifying anything in node_modules, excluding it seems reasonable.
With Cygwin and bash shell, you can do this:
$ find $THEDIR -type d -exec fsutil file setCaseSensitiveInfo "{}" enable \;
It appears that Windows handles the '/' characters output by the find command just fine.
In my case I had to first enable the Linux subsystem before using the fsutil tool. So my steps were:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
then restart, and then #robdy 's solution:
(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {fsutil.exe file setCaseSensitiveInfo $_ enable}
On windows 11, the other answers are not correct, as fsutil requires that the directory is not empty. To overcome this, I created a NEW empty directory, used fsutil file setCaseSensitiveInfo to set the case sensitive flag on the new directory, then MOVED the files from the other directory inside the new one. This works, as the directories are re-created when moved, and new directories inherit the case sensitive flag.

Zipping folders in powershell

Hope fellow scripters can help with this one :) Been breaking my head around the problem for few hours now.
I'm trying to zip up certain folders using powershell.
My folder structure is
Backups
BoxIntranet
Components
Content
Database
Exec
Files
Logs
Multibrowser
Multibrowser\Legacy\Customisation
Packages
ParentPortal
ParentPortal\customisation
StudentPortal
StudentPortal\customisation
Update
WebDav
There are a lot more files and folders in every one of the above but these are the ones I'm mainly interested in.
I am trying to zip it all up using either Write-Zip or Compress-Archive methods in PowerShell but my conditions are.
Only Content, Files, Database folders should be zipped from root
Multibrowser\Legacy\customisation, StudentPortal\Customisation and ParentPortal\customisation folders should also be backed up.
Folder structure should remain the same in the zip file meaning that Root of the zip file should have Content, Files, Database, Multibrowser, ParentPortal and StudentPortal folders. Whilst Content, Files and Database folders should have everything zipped up, Multibrowser, ParentPortal and StudentPortal folders should only have the specified sub directories and all files within them.
Code:
$FilesAndInclude = #("Content", "Files", "Database", "Multibrowser\Legacy\customisation",
"StudentPortal\customisation", "ParentPortal\customisation",
"BoxIntranet\customisation")
$FilesToExclude = #("connectionstrings.config", "inc_dbconn.asp")
Get-ChildItem -Path "C:\Folder" -Include $FilesAndInclude -Recurse -Exclude $FilesToExclude|
Compress-Archive -DestinationPath "Archive.zip"
I've tried the above and it doesn't do anything however if I remove the -Include parameter then it zips up everything however doesn't retain folder structure.
Is there any way to complete what I am after within powershell?
Ok, first things first, the reason that you are having a hard time using the -Include parameter is because it is designed to exclusively include only the things you specify. As such, it will look at the name of things (not their path), and check against the list and if it matches something in the list it will include that item. Since you only list folder names it is only including those folders (but not their contents). So you aren't getting any files passed down the pipe this way. To get around that you'll need to build your file list first, then pipe it to the cmdlet to zip things up.
Next issue is that Compress-Archive doesn't store path info, so you'll need to use Write-Zip. I have included what I think you would want for that cmdlet.
$FilesAndInclude = #("Content", "Files", "Database", "Multibrowser\Legacy\customisation",
"StudentPortal\customisation", "ParentPortal\customisation",
"BoxIntranet\customisation")
$FilesToExclude = #("connectionstrings.config", "inc_dbconn.asp")
[array]$FilesToZip = Get-ChildItem .\* -Exclude $FilesToExclude -File
$FilesToZip += $FilesAndInclude | ForEach{Get-ChildItem .\$_ -Exclude $FilesToExclude -File}
$FilesToZip | Write-Zip -EntryPathRoot $(Resolve-Path .\|Select -Expand Path) -OutputPath Archive.zip

Find directories two levels down that do not contain certain file

I have done some Windows batch scripting, but I have never worked with PowerShell, so I am looking for some startup help.
I would like to
parse a directory tree
find all the directories two levels down that do not contain folder.jpg
write the list of these directories to a text file
So far I have found this link which addresses part of the question. I have also found that Get-ChildItem \*\*\* should get me to the directories two levels down.
I would appreciate it if someone could help me put this together.
Thanks a lot
You need a combination of Get-Child, Foreach-Object, Test-Path, Join-Path and Write-Object:
Get-ChildItem *\*\* -Directory | ForEach-Object {if(!(Test-Path(Join-Path -Path $_ -ChildPath "folder.jpg"))) {Write-Output $_}}
This will write all the DirectoryInfo object where the file doesn't exist to the pipeline. You can then opt to write them to a file.