In short, I have an Ubuntu file server, connected to a windows desktop, through SMB protocol, so the directories can be viewed as you do on a windows computer. For some reason files seem to disappear from the file server in a particular folder, which I frequent so I know I unwittingly delete things. I wrote a PowerShell script to check this folder for me and check what all the files are in the folder and remember them in a list formed by the script, to then be compared to and updated each time the script runs and specifically tell me when files are missing. The script will create a list of the files and then compare that list to the current contents of the folder each time it runs, alerting me if any files are missing.
I was going to make it a .bat script, but PowerShell has built in functions that would make it easier. And I had to modify my plan so that I would have two scripts, one to create the list of file contents recursively, and a second script that will check that list against the folder contents later. If I want to update the list I have to re-run the first script. That is just it's current iteration though. Perhaps there is a way to get it to run off one script but I don't know, this was just my instructors suggestion on the matter.
The first script I wrote is here:
# Script: CreateFileList.ps1
# Open a dialog box for folder selection
Add-Type -AssemblyName System.Windows.Forms
$folder = [System.Windows.Forms.FolderBrowserDialog]::new()
$null = $folder.ShowDialog()
# Get the selected folder path
$selectedPath = $folder.SelectedPath
# Check if a folder was selected
if (-not [string]::IsNullOrEmpty($selectedPath)) {
# Define the output CSV file
$csvFile = "file_list.csv"
# Get the list of all files and folders recursively
$fileList = Get-ChildItem -Path $selectedPath -Recurse | Select-Object FullName
# Export the list to a CSV file
$fileList | Export-Csv -Path $csvFile -NoTypeInformation
Write-Host "File list created and saved to $csvFile"
} else {
Write-Host "No folder selected."
}
The second script is here:
# Script: CheckForMissingFiles.ps1
# Open a dialog box for folder selection
Add-Type -AssemblyName System.Windows.Forms
$folder = [System.Windows.Forms.FolderBrowserDialog]::new()
$null = $folder.ShowDialog()
# Get the selected folder path
$selectedPath = $folder.SelectedPath
# Check if a folder was selected
if (-not [string]::IsNullOrEmpty($selectedPath)) {
# Define the path to the CSV file
$csvFile = "file_list.csv"
# Check if the CSV file exists
if (-not (Test-Path $csvFile)) {
Write-Host "CSV file not found. Please run the script to create the file list first."
exit
}
# Import the original file list from the CSV
$originalList = Import-Csv -Path $csvFile | Select-Object -ExpandProperty FullName
# Get the current list of files and folders recursively
$currentList = Get-ChildItem -Path $selectedPath -Recurse | Select-Object -ExpandProperty FullName
# Compare the original list with the current list
$missingFiles = $originalList | Where-Object { $_ -notin $currentList }
if ($missingFiles) {
Write-Host "The following files/folders are missing:"
$missingFiles
} else {
Write-Host "No files/folders are missing."
}
} else {
Write-Host "No folder selected."
}
I tested the script. When you click it, you have to right-click on it and select to run in PowerShell, because left-clicking it just opens it for editing for reasons I don't yet understand. Then it will open a window that will have you specify what folder you want to take an account of and it will take a moment depending on the size of the folder and how many files it contains, but it will then export a .csv file that will show all the contents of the folder with full names and their file formats.
The second script when run didn't seem to produce any results. This is when my instructor was looking at it and checked the end of the second script and realized that it spits out the results but it isn't pausing at the end so I have any time to even register that results were given before they disappear. So we added a pause at the end.
So literally just like this for the end of the second script:
} else {
Write-Host "No folder selected."
}
pause
That resulted in it leaving an open prompt window that now shows that there are many missing files, so technically the two scripts in conjunction with each other worked perfectly. And they work with a networked drive located on a Linux system, from a Windows PowerShell script. So that was a happy result.
The problem now is that when the second script compared the results against the .csv of the first script of the file contents where files seem to magically disappear all the time and I need to know which ones, the second script returned results for many missing files that I then went to check to see if they were gone and they were still there. What gives? However I did notice something.
A movie file I was supposedly missing but confirmed was not missing on my server was named: "Clint Eastwood Dollar Trilogy I A Fistful Of Dollars 1964 Clint Eastwood Marianne Koch José Calvo.mp4" while the name given to it by the first script which exports the .csv file calls it: "Clint Eastwood Dollar Trilogy I A Fistful Of Dollars 1964 Clint Eastwood Marianne Koch Jos? Calvo.mp4"
Instead of the accent over the E in 'Jose Calvo', the script or the character base used to create the script didn't recognize it and put "Jos?" instead of Jose with the accent over the E, and so this was counted as one of the missing files from the original list. The second script saw the file with the accent over the letter E on this file and similar discrepancies in all other cases, it saw those correctly named files on the server but is not programmed to tell me that "hey, this file with the question mark wasn't found but one without it was found that was not included in the .csv file", and it also isn't programmed to know the difference. So it didn't see script 1's error with the question mark replacing the E with the accent and then script 2 returned the output saying that the file with the question mark couldn't be found. And it did the same with all other files that it found the same discrepancy with.# Export the list to a CSV file
$fileList | Export-Csv -Path $csvFile -NoTypeInformation
Write-Host "File list created and saved to $csvFile"
# Export the list to a CSV file
$fileList | Export-Csv -Path $csvFile -NoTypeInformation -Encoding UTF8
Write-Host "File list created and saved to $csvFile"
# Script: CheckForMissingFiles.ps1# Open a dialog box for folder selectionAdd-Type -AssemblyName System.Windows.Forms$folder = [System.Windows.Forms.FolderBrowserDialog]::new()$null = $folder.ShowDialog()# Get the selected folder path$selectedPath = $folder.SelectedPath# Check if a folder was selectedif (-not [string]::IsNullOrEmpty($selectedPath)) {# Open a dialog box to select the CSV fileAdd-Type -AssemblyName System.Windows.Forms$csvFileDialog = [System.Windows.Forms.OpenFileDialog]::new()$csvFileDialog.Filter = "CSV Files (*.csv)|*.csv"$null = $csvFileDialog.ShowDialog()# Get the selected CSV file path$csvFile = $csvFileDialog.FileName# Check if a CSV file was selectedif (-not [string]::IsNullOrEmpty($csvFile)) {}# Import the original file list from the CSV with UTF-8 encoding$originalList = Import-Csv -Path $csvFile -Encoding UTF8 | Select-Object -ExpandProperty FullName# Get the current list of files and folders recursively$currentList = Get-ChildItem -Path $selectedPath -Recurse | Select-Object -ExpandProperty FullName# Compare the original list with the current list$missingFiles = $originalList | Where-Object { $_ -notin $currentList }if ($missingFiles) {Write-Host "The following files/folders are missing:"$missingFiles} else {Write-Host "No files/folders are missing."}} else {Write-Host "No CSV file selected."}pause
No comments:
Post a Comment