Deleting a folder out of all user directories - powershell

I'm trying to delete a folder out of the \AppData\Local\Microsoft_Corporation directory for all users on a given computer. I found a few PowerShell script that can complete this task for me but extra wrinkle here is that this folder name is slightly different for every user. The folder name I'm trying to remove looks like this - harmony_Path_lzm5ceganmb1ihkqq2. It always has the word "harmony" in the folder name, so I'm trying to search for any folder with this keyword and remove it.
This is the script I have so far:
$users = Get-ChildItem C:\Users
foreach ($user in $users){
$folder = "$($user.fullname)\AppData\Local\Microsoft_Corporation\*"
If (Test-Path $folder) {
Remove-Item $folder -Recurse -Force -ErrorAction silentlycontinue -WhatIf
}
}
This seems to work fine to remove every folder in \AppData\Local\Microsoft_Corporation\ but when I try to search for "harmony" keywords with the Where-Object Cmdlet. I can't get it to work correctly.
$users = Get-ChildItem C:\Users
foreach ($user in $users){
$folder = "$($user.fullname)\AppData\Local\Microsoft_Corporation\* | Where-Object {$_.Name -like "*harm*"}"
If (Test-Path $folder) {
Remove-Item $folder -Recurse -Force -ErrorAction silentlycontinue -WhatIf
}
}
Can anyone help me with this?

$users = Get-ChildItem C:\Users
foreach ($user in $users){
$folder = "$($user.fullname)\AppData\Local\Microsoft_Corporation\*Harmony*"
If (Test-Path $folder) {
Remove-Item $folder -Recurse -Force -ErrorAction silentlycontinue -WhatIf
}
}
$folder contains a string - path. It does not contains list of files to use Where-Object Cmdlet.
Another way:
Get-ChildItem "C:\Users\*\AppData\Local\Microsoft_Corporation\*harmony*" -Directory | Remove-Item -WhatIf

why did you put where-object inside " " ? powershell read this as a string
try using this:
$users = Get-ChildItem C:\Users
foreach ($user in $users){
$folder = "$($user.fullname)\AppData\Local\Microsoft_Corporation\"
If (Test-Path $folder) {
Get-ChildItem $folder -Recurse | Where-Object {$_.Name -like "*harm*"}|Remove-Item -Force -ErrorAction silentlycontinue
}
}

Related

PowerShell works only when running in a console and not as a PS1 executable file

I am fairly new to PowerShell and am having challenges trying to get a PS1 executable file to work. Running the script in a PowerShell console works completely fine and copy's items and creates the correct log filename.
The expectation would be to Right-click the PS1 file containing the script, run the script with "Run with PowerShell", and then allow the script to finish with a log file populated and files copied when user prompt selects yes.
At this point, there are no errors messages, other than the PS1 file script gets replaced by ton of unrecognizable symbols/characters and creates the log file as "Box Project Files.ps1JobFileLocations.log" instead of "JobFileLocations.log".
The PowerShell version being used is 5.1. Windows 10 OS. Set-ExecutionPolicy was set to Unrestricted and confirmed as Unrestricted for CurrentUser and LocalMachine. Unblock-File was also tried.
Below is the script that works in a PowerShell Console but not as a PS1 executable file.
# Drawing Tag Searches
$MechDWGFilterList = #('*IFC*','*mech*', '*permit*', '*final*')
$DatabaseFilterList = #('*field*','*software*')
# Root folder and destination folder
$JobNumber = '*'+(Read-Host -Prompt 'Enter in job number')+'*'
$srcRoot = 'C:\Users\username\Box\'
$JobRoot = (Get-ChildItem -Path $srcRoot -Filter "*Active Projects*" -Recurse -Directory -Depth 1).Fullname
$dstRoot = $MyInvocation.MyCommand.Path
# Find job numer pdf file
$JobFolder = (Get-ChildItem -Path $JobRoot -Filter "$JobNumber" -Recurse -Directory -Depth 0).Fullname
$Logfile = $dstRoot+"JobFileLocations.log"
$reply = Read-Host -Prompt "Make a copy of relevant project files to local drive?[y/n]"
# Find sub-folder from job folder
$ProposalFolder = (Get-ChildItem -Path $JobFolder -Filter "*Proposals*" -Recurse -Directory).Fullname
$MechDWGFolder = (Get-ChildItem -Path $JobFolder -Filter "*Plans*" -Recurse -Directory).Fullname
$SubmittalFolder = (Get-ChildItem -Path $JobFolder -Filter "*Submittal*" -Recurse -Directory).Fullname
$DatabaseFolder = (Get-ChildItem -Path $JobFolder -Filter "*Backup*" -Recurse -Directory).Fullname
$EstimateFolder = (Get-ChildItem -Path $JobFolder -Filter "*Estimate*" -Recurse -Directory).Fullname
# Find files from list
$ProposalList = Get-ChildItem -Path $ProposalFolder -Filter '*proposal*.pdf' -r | Sort-Object -Descending -Property LastWriteTime | Select -First 1
$MechDWGList = Get-ChildItem -Path $MechDWGFolder -Filter *.pdf -r | Sort-Object -Descending -Property LastWriteTime
$SubmittalList = Get-ChildItem $SubmittalFolder -Filter '*submittal*.pdf' -r | Sort-Object -Descending -Property LastWriteTime | Select -First 1
$DatabaseList = Get-ChildItem $DatabaseFolder -Filter *.zip -r | Sort-Object -Descending -Property LastWriteTime | Select -First 1
$EstimateList = Get-ChildItem -Path $EstimateFolder -Filter *.xl* -r | Sort-Object -Descending -Property LastWriteTime
# Log file path location and copy file to local directory
# Function to add items to a log text file
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
# Log file path location and copy file to local directory
LogWrite "::==========================================::`n|| Project Document Paths ||`n::==========================================::"
LogWrite "`nNote: If a section has more than one file path, files are listed from most recent to oldest.`n"
LogWrite "----------Scope Document/Proposal(s)----------"
foreach ($file in $ProposalList)
{
LogWrite $file.FullName
if ( $reply -match "[yY]" )
{
Copy-Item -Path $($file.FullName) -Destination $dstRoot
}
}
LogWrite "`n-------------Mechanical Drawing(s)------------"
foreach ($file in $MechDWGList)
{
# Where the file name contains one of these filters
foreach($filter in $MechDWGFilterList)
{
if($file.Name -like $filter)
{
LogWrite $file.FullName
if ( $reply -match "[yY]" )
{
Copy-Item -Path $($file.FullName) -Destination $dstRoot
}
}
}
}
LogWrite "`n-------------Controls Submittal(s)------------"
foreach ($file in $SubmittalList)
{
LogWrite $file.FullName
if ( $reply -match "[yY]" )
{
Copy-Item -Path $($file.FullName) -Destination $dstRoot
}
}
LogWrite "`n-------------------Database-------------------"
foreach ($file in $DatabaseList)
{
LogWrite $file.FullName
if ( $reply -match "[yY]" )
{
Copy-Item -Path $($file.FullName) -Destination $dstRoot
}
}
LogWrite "`n------------------Estimate(s)-----------------"
foreach ($file in $EstimateList)
{
LogWrite $file.FullName
if ( $reply -match "[yY]" )
{
Copy-Item -Path $($file.FullName) -Destination $dstRoot
}
}
# If running in the console, wait for input before closing.
if ($Host.Name -eq "ConsoleHost")
{
Write-Host "Press any key to continue..."
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null
}
Could someone help me understand what is wrong with running the script as a PS1 file?
The problem with your script is this particular line:
$dstRoot = $MyInvocation.MyCommand.Path
$MyInvocation.MyCommand.Path resolves the rooted filesystem path to the script itself - which is why you get Box Project Files.ps1 (presumably the name of the script) in the log path.
The get the path of the parent directory of any file path, you can use Split-Path -Parent:
$dstRoot = Split-Path -LiteralPath $MyInvocation.MyCommand.Path -Parent
That being said, since Windows PowerShell 3.0, both the directory and script file paths have been available via the $PSCommandPath and $PSScriptRoot automatic variables, so you can simplify the code to just:
$dstRoot = $PSScriptRoot

nothing returned to variable when assigning to recursive gci search omitting folders using powershell v2

I am trying to recursively search for files on a windows 7 machine + network drives attached to it while excluding certain folders i.e. C:\windows & all recursive folders in this such as system32.
I know this question has been asked before but following the answers has not helped and I am still left with a blank variable.
Here are the combinations I have tried:
$AllDrives = Get-PSDrive
$files=#("*.xml",*.txt)
foreach ($Drive in $AllDrives) {
if ($Drive.Provider.Name -eq "FileSystem") {
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notlike "*Windows*" -and $_.PSParentPath -notlike "*Microsoft*"
}
}
I have also tried these combinations:
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notmatch "Program Files|Users|Windows"}
$exclude_pattern = $drive.root + "Windows"
$filenames = Get-ChildItem -Force -Recurse -path $drive.root -Include $files -Attributes !Directory+!System -ErrorAction "SilentlyContinue" | Where-Object { $_.PSIsContainer -eq $false } | Where-Object { $_.FullName -notmatch $exclude_pattern }
Unfortunately, after an amount of time has elapsed, when I type $filename into the terminal nothing has been assigned to it.

foreach loop to copy file into all directories in c:\users\ ... hopefully a simple one

Aim: I need to copy and paste Teams backgrunds into all users profiles on lots of machines
Error: Path does not exist.
I can't figure out the issue why my path C:\users\user1\Appdata turns into C:\Users1 Users2\Appdata
Here is the full code:
$Folders = Get-ChildItem -Directory "C:\Users" | Where-Object {$_.Name -notlike "Public"} | Where-Object {$_.Name -notlike "AppData"}
$Backgrounds = "\\Server1\Teams-Backgrounds\*"
Foreach($Folder in $Folders) {
Copy-Item -Path $Backgrounds -Destination "C:\Users\$($Folders.Name)\AppData\Roaming\Microsoft\Teams\Backgrounds\Uploads" -Force -ErrorAction Stop
}
This is what you are after.
# Combined the Where-Object filter into a single
$Folders = Get-ChildItem -Directory "C:\Users" | Where-Object {($_.Name -notlike "Public") -and ($_.Name -notlike "AppData")}
$Backgrounds = "\\Server1\Teams-Backgrounds\*"
Foreach($Folder in $Folders) {
# Changed $Folders.Name to $Folder.Name
Copy-Item -Path $Backgrounds -Destination "C:\Users\$($Folder.Name)\AppData\Roaming\Microsoft\Teams\Backgrounds\Uploads" -Force -ErrorAction Stop
}

How compare Home folders and Active Directory with copy/remove folders?

i working on one project and i have problem. Assignment: The powershell script must compare Home user folders on F:UserHome with AD by name. If name folder is same with name in ActiveDirectory, dont do anything and continue.
But if user isn't in AD, script must compare:
If home adressar contains data, move this adresar from F: to Synology NAS(it is another server).
If home adressar is empty, it can be remove/delete.
But i must sort this home adresar to 2 folders(UserToMove.txt/UserToRemove.txt) for my boss too - with the same conditions.
If you don't understand something, I can explain it again. It's very important for me.
Here is my script, which i create, but isn't working: - there's a mess in it
$homeDriveRoot = "F:\UserHome"
$leaversRoot = "\new storage on NAS"
$folders = Get-ChildItem $homeDriveRoot | Select -ExpandProperty Name
foreach($folder in $folders) {
$folder
#Compare by name
$u = Get-ADUser -identity $folder -Filter {Enabled -eq $true}|Select ExpandProperty Name
#If>0
if (($u).count -gt 0) {
#If empty - remove
if(($u) -eq $null){ Copy-Object -Path "$homeDriveRoot$_" -Destination C:\Users\branym.adm\desktop\remove.csv -Force}
#If<0 write to file
else{Copy-Object -Path "$homeDriveRoot$_" -Destination C:\Users\branym.adm\Desktop\active.csv -Force};
}
#If dont search
else { echo "lost $u folder"}
}
I think this may help you:
$homeDriveRoot = "F:\UserHome"
$leaversRoot = "\new storage on NAS"
# create two variables for the output text files. (they will end up on your desktop)
$removeFile = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath 'UserToReMove.txt'
$moveFile = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath 'UserToMove.txt'
# check if the destination folder in $leaversRoot exists. If not create it first
if (!(Test-Path -Path $leaversRoot -PathType Container)) {
New-Item -Path $leaversRoot -ItemType Directory | Out-Null
}
# get a list of all folders in the $homeDriveRoot.
# The items in the list are FolderInfo objects, not simply strings.
# If your PowerShell version is less than 3.0, write it like this:
# $folders = Get-ChildItem -Path $homeDriveRoot | Where-Object { $_.PSIsContainer }
$folders = Get-ChildItem -Path $homeDriveRoot -Directory
foreach($folder in $folders) {
# see if we can find an AD user with this SamAccountName
$user = Get-ADUser -Identity $folder.BaseName
if (!$user -or $user.Enabled -eq $false) {
# there is no active AD user found for this folder name
# test if the folder is empty or not
# by using Select-Object -First 1 the enumeration of files and/or folders stops at the first item
if ((Get-ChildItem -Path $folder.FullName -Force | Select-Object -First 1 | Measure-Object).Count -eq 0) {
# the folder is empty, so it can be deleted
# Add a line to the $removeFile
Add-Content -Path $removeFile -Value $folder.BaseName
Remove-Item -Path $folder.FullName -Force -Confirm:$false -WhatIf
}
else {
# the folder has items in it, so move it to NAS
# Add a line to the $moveFile
Add-Content -Path $moveFile -Value $folder.BaseName
Move-Item -Path $folder.FullName -Destination $leaversRoot -Force -WhatIf
}
}
}
Take off the -WhatIf switches from the Remove-Item and Move-Item cmdlets if the results are what you expect.
These switches are for testing and nothing actually gets moved or removed.

Powershell - delete old folders but not old files

I have the following code to keep on top of old folders which I no longer want to keep
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } |
Remove-Item -Force -EA SilentlyContinue
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path
$_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer })
-eq $null } | Remove-Item -Force -Recurse -EA SilentlyContinue
It deletes anything older than a certain number of days ($limit) including files and folders.
However, what I am after is ONLY deleting old folders and their contents.
For example, a day old folder may have file within that is a year old but I want to keep that folder and the old file. The code above keeps the folder but deletes the file. All I want to do is delete folders (and their contents) within the root that are older than the $limit else leave the other folders and content alone.
Thanks in advance.
Well look at this bit:
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { !$_.PSIsContainer -and $_.CreationTime -ge $limit } |
Remove-Item -Force -EA SilentlyContinue
It's basically saying "everything not a folder and older than specified is removed". So your first step is to remove that.
The second part is just deleting empty folders, you can keep it as-is or you could add to the Where statement to include the CreationTime:
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { $_.PSIsContainer -and $_.CreationTime -lt $limit -and (Get-ChildItem -Path
$_.FullName -Recurse -Force | Where-Object { $_.CreationTime -lt $limit })
-eq $null } | Remove-Item -Force -Recurse -EA SilentlyContinue
The second Where statement returns a list of files and folders newer than $limit, and only deletes the folder if that is null.