Script to remove specific Files from particular machine

Hi All,
As per the below thread, I got a superb script to remove files from specific locations. the only downside to this one is that if there are multiple files on the same host and the machine is offline, each and every file it checks if machine is offline and then update machine offline status. Can it be changed to detect if the machine is offline once, then other consecutive entries it should directly mark as machine offline:

https://www.experts-exchange.com/questions/28514537/Delete-files-from-file-path-against-corresponding-machine-which-are-listed-in-a-CSV.html

Script:
# CSV Needs Header row - Host,Path,Status
$csvPath = "C:\RemoveFiles.csv"
$csv = Import-Csv $csvPath
$csv | ForEach-Object {
    $computer = $_.Host
    $path = $($_.Path) -replace [char]34,""
    $status = $_.Status
    $props = @{
        "Host" = $computer;
        "Path" = $path;
        "Status" = $status
    }
    $obj = New-Object -TypeName PSObject -Property $props
      Write-Host ""
      if ($status -eq "") {
        if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
            $dollarShare = $path -replace ":","$"
            $uncPath = "\\$computer\$dollarShare"
            if (Test-Path -Path $uncPath) {
                $deleted = $true
                try {
                    Remove-Item -Path $uncPath -Force
                } catch {
                    $deleted = $false
                    $obj.Status = "Could not delete"
                    Write-Host "Unable to remove file on $($computer.ToUpper()) from $($path)"
                }
                if ($deleted) {
                    $obj.Status = "Deleted"
                    Write-Host "Successfully removed file on $($computer.ToUpper()) from $($path)"
                }
            } else {
                $obj.Status = "Missing"
                Write-Host "Missing file on $($computer.ToUpper()) from $($path)"
            }
        } else {
            Write-Host "Host $($computer.ToUpper()) is offline"
                  $obj.Status = "Machine Offline"
        }
    } else {
        Write-Host "File Already Deleted on $($computer.ToUpper()) from $($path)"
    }
      Write-Host ""
    Write-Output $obj
} | Export-Csv -Path $csvPath -Force -NoTypeInformation
qgmasterAsked:
Who is Participating?
 
oBdAConnect With a Mentor Commented:
Try this:
# CSV Needs Header row - Host,Path,Status
$CsvPath = "C:\RemoveFiles.csv"
$Csv = Import-Csv -Path $CsvPath
$Csv | Group-Object -Property Host | ForEach-Object {
	Write-Host "Processing $($_.Name.ToUpper()) ..." -ForegroundColor White
	If (Test-Connection -ComputerName $_.Name -Count 1 -Quiet) {
		$_.Group | ForEach-Object {
			If ('Deleted', 'Missing' -contains $_.Status) {
				Write-Host "Already processed '$($_.Path)' on $($_.Host.ToUpper())" -ForegroundColor White
			} Else {
				$UncPath = "\\$($_.Host)\$($_.Path.Replace("$([char]34)", '').Replace(':', '$'))"
				If (Test-Path -Path $UncPath) {
					Try {
						Remove-Item -Path $UncPath -ErrorAction Stop
						$_.Status = 'Deleted'
						Write-Host "Removed '$($_.Path)' on $($_.Host.ToUpper())" -ForegroundColor Green
					} Catch {
						Write-Host "Unable to remove '$($_.Path)' on $($_.Host.ToUpper())" -ForegroundColor Red
						$_.Status = 'Could not delete'
					}
				} Else {
					Write-Host "Could not find '$($_.Path)' on $($_.Host.ToUpper())" -ForegroundColor Yellow
					$_.Status = 'Missing'
				}
			}
			$_
 		}
	} Else {
		Write-Host "$($_.Name.ToUpper()) is offline" -ForegroundColor Red
		$_.Group | ForEach-Object {
			$_.Status = 'Machine Offline'
			$_
		}
	}
	Write-Host ''
} | Export-Csv -Path $CsvPath -Force -NoTypeInformation

Open in new window

0
 
yo_beeDirector of Information TechnologyCommented:
I am looking at your script and it looks like it should skip the machines.
2017-12-28_8-52-43.pngWhat is happening or maybe I am not understanding what you are looking to adjust.

Can you post an example of the csv output you would like to see?
0
 
oBdACommented:
Sorry, but yo_bee's comment doesn't really help here.
The issue is not that the machines aren't skipped; qgmaster already pointed out that there is a connection check in place.
The issue is that the csv can contain the same computer name multiple times, with a different path to delete in each row.
In the original script, each line in the csv is processed, and for each line, the respective computer pinged - multiple times if there are multiple files to delete for that machine, even if this computer has already been determined to not respond. This slows things down considerably if the machine is offline and the script has to wait for the (lost) ping multiple times.
Pseudo code:
ForEach (<Row>) {
	If (Test-Connection <Row.Host>) {
		<delete file>
	} Else {
		<mark offline>
	}
}

Open in new window

In other words, a csv like this
OfflinePC,File1
OfflinePC,File2
OfflinePC,File3
would be processed like this:
(Row with File1) Test-Connection OfflinePC fails
(Row with File2) Test-Connection OfflinePC fails
(Row with File3) Test-Connection OfflinePC fails
where the second and third ping are obviously unnecessary.
This is what qgmaster was aiming at with "Can it be changed to detect if the machine is offline once, then other consecutive entries it should directly mark as machine offline"

The script in https:#a42417643 solves this by grouping the rows by computers first and then processing each group depending on whether the computer responds.
Pseudo code:
ForEach (<Computer>) {
	If (Test-Connection <Computer>) {
		ForEach (<File On This Computer>) {
			<delete file>
		}
	} Else {
		<mark offline>
	}
}

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.