Reputation: 11
I have the need to search all servers in our domain for specific folders, I already have a script here
function Find-ComputersWithFolder {
# Get all computers in the Active Directory domain
$computers = Get-ADComputer -Filter {name -like 'servernamehere' }
# Initialize an empty array to store the result
$result = @()
# Iterate through each computer
foreach ($computer in $computers) {
$computerName = $computer.Name
# Check if the folder C:\ASNEXT exists on the computer
$folderExists = Test-Path "\\$computerName\C$\Windows\WinSxS\foldernamehere"
# If the folder exists, add the computer name to the result list
if ($folderExists) {
$result += $computerName
}
}
# Return the result array
return $result
}
# Usage example for the Find-ComputersWithFolder function
# Find all computers with the folder
$computersWithFolder = Find-ComputersWithFolder
# Output the result
Write-Output "Computers with folder"
$computersWithFolder
what this does is searches all servers in the domain and looks for the folder that is specified in the line
$folderExists = Test-Path "\\$computerName\C$\Windows\WinSxS\foldernamehere"
However i have a long list of folders i would like to supply to this script so that it went through them instead of me having to manually specify the folder on the specific line
$folderExists = Test-Path "\\$computerName\C$\Windows\WinSxS\foldernamehere"
I tried the following amendment to the script, i put all the folder names in a text file and created a variable $Paths to which i used the get-content.
$paths = get-content C:\scripts\paths.txt
This works in that it fills the variable with the list of folders but when i change the line that actually searches to this
$folderExists = Test-Path "\\$computerName\C$\Windows\WinSxS\$paths"
I dont get any output, I suspect its is something to do with having to somehow get it to do a for-each through the list but i dont know how to get to that point.
Any help would be much appreciated
Upvotes: 0
Views: 236
Reputation: 11
I managed to get it with
function Search-ComputersForFolders {
param (
[Parameter(Mandatory=$true)]
[string]$FilePath
)
# Read the folder names from the text file
$folderNames = Get-Content C:\scripts\paths.txt
# Get all computers in the network
$computers = Get-ADComputer -Filter {name -like 'servernames'} | Select-Object -ExpandProperty Name
# Initialize an empty array to store the found folders
$foundFolders = @()
# Loop through each computer and search for the folders
foreach ($computer in $computers) {
# Construct the UNC path to the computer's C drive
$uncPath = "\\$computer\C$"
# Check if the UNC path is accessible
if (Test-Path -Path $uncPath) {
# Loop through each folder name and search for it
foreach ($folderName in $folderNames) {
# Construct the full path to the folder
$folderPath = Join-Path -Path $uncPath -ChildPath $folderName
# Check if the folder exists
if (Test-Path -Path $folderPath -PathType Container) {
# Add the found folder to the array
$foundFolders += Get-Item -Path $folderPath
}
}
}
}
# Output the found folders
return $foundFolders
}
# Usage example for the Search-ComputersForFolders.ps1 script
# Example: Search for folders on all computers in the network
# ----------------------------------------------------------------------------
$folderFilePath = "C:\scripts\paths.txt"
$foundFolders = Search-ComputersForFolders -FilePath $folderFilePath
# Output the found folders
foreach ($folder in $foundFolders) {
Write-Output "Found folder: $($folder.FullName)"
}
Upvotes: 0
Reputation: 60848
"I suspect its is something to do with having to somehow get it to do a for-each through the list..."
This is correct, you're missing an inner loop to test each path in $paths
for each computer in $computers
, however, what I would recommend you to do is to remove complexity from your function, the query for Active Directory computers should be outside of your function, then you can leverage the pipeline by taking ValueFromPipelineByPropertyName
:
function Test-NetworkPath {
param(
[Parameter(ValueFromPipelineByPropertyName, Mandatory)]
[Alias('Name')]
[string] $ComputerName,
[Parameter(Mandatory, Position = 0)]
[string[]] $Path
)
process {
foreach ($p in $Path) {
$pathToTest = '\\{0}\C$\Windows\WinSxS\{1}' -f $ComputerName, $p
if (Test-Path $pathToTest) {
$pathToTest
}
}
}
}
$paths = Get-Content C:\scripts\paths.txt
Get-ADComputer -Filter "name -like 'servernamehere'" |
Test-NetworkPath -Path $paths
In this example the .Name
property from each ADComputer
object is bound thru the pipeline to the $ComputerName
parameter.
Upvotes: 1