I am writing an Active Directory script that needs to determine which Server Cluster each clients personal data resides on.
Here is pseudocode form of what I have writting
$HostedClients = Get all OU and subOU's of the Active Directory Tree
foreach ($client in $hostedClients)
{
$RandomUser = Get a Random User within OU and grab his/her H: drive path
$ServerCluser = Get the Root folder of the Path.
}
Here is a Sample output of the list of Clients and a ‘sample’ H: drive path from each.
Fishman \\cfs03\healthpcp-users$\Fishman\anna.pirog
Golden \\cfs03\healthpcp-users$\golden\mnava
HH \\cfs03\healthpcp-users$\hh\drashidi
SHCS \\cfs03\healthpcp-users$\hshcs\lsalems
GA \\cfs03\healthpcp-users$\jandrews
CLD \\cfs03\healthpcp-users$\jschin
Kamboj \\cfs03\healthpcp-users$\kamboj\tcooper
Kare \\cfs03\healthpcp-users$\kare\nhemkes1
Problem
As you can see, depending on how the AD folder structure is setup, the number of ‘folders’ in the UNC path may be different per OU.
The pseudocode line “$ServerCluser = Get the Root folder of the Path” I tried to accomplish with the following command
This retrieved results for ‘most’ of them, but since I had a different number of folders for some, it retrieved the wrong results.
Is there a way I can take the root folder name of any length UNC path and retrieve the name of the root? The only ‘solution’ I can see is to devise a separate function that ‘counts’ the number of folder depths and then capture that number with a variable and then do the split on that value.
It’s much easier to provide what the expected result is. You can usually get what you want by doing some math and referencing by index. Here are some examples of how you can manipulate the index:
$shares = @{
"Fishman" = "\\cfs03\healthpcp-users$\Fishman\anna.pirog"
"Golden" = "\\cfs03\healthpcp-users$\golden\mnava"
"HH" = "\\cfs03\healthpcp-users$\hh\drashidi"
"SHCS" = "\\cfs03\healthpcp-users$\hshcs\lsalems"
"GA" = "\\cfs03\healthpcp-users$\jandrews"
"CLD" = "\\cfs03\healthpcp-users$\jschin"
"Kamboj" = "\\cfs03\healthpcp-users$\kamboj\tcooper"
"Kare" = "\\cfs03\healthpcp-users$\kare\nhemkes1"
}
foreach ( $share in $shares.GetEnumerator() ) {
$arr = $share.Value.split("\")
"{0} upperbound is {1}" -f $share.Key, $arr[-1]
"{0} one folder up is {1}" -f $share.Key, $arr[$arr.Count - 2]
"{0} first folder after share {1} `r`n" -f $share.Key, $arr[4]
}
Output:
SHCS upperbound is lsalems
SHCS one folder up is hshcs
SHCS first folder after share hshcs
Fishman upperbound is anna.pirog
Fishman one folder up is Fishman
Fishman first folder after share Fishman
CLD upperbound is jschin
CLD one folder up is healthpcp-users$
CLD first folder after share jschin
Golden upperbound is mnava
Golden one folder up is golden
Golden first folder after share golden
Kamboj upperbound is tcooper
Kamboj one folder up is kamboj
Kamboj first folder after share kamboj
Kare upperbound is nhemkes1
Kare one folder up is kare
Kare first folder after share kare
GA upperbound is jandrews
GA one folder up is healthpcp-users$
GA first folder after share jandrews
HH upperbound is drashidi
HH one folder up is hh
HH first folder after share hh
Thanks for your input. This is my ‘finished’ project which is just a reconnaissance script for me as I push along and create another script that will eventually ‘fix’ users H: drive permissions (we have been getting hit with Crypto-Locker Malware derivatives and they have been spreading due to incorrect NTFS permissions). First step, I have to determine which Server their files are located.
I’m somewhat of a noob when it comes to Powershell, but I am finding that the remote functionality and the remote execution capability is becoming really handy, so I trying to get up to speed quickly.
If you have any ‘critiques’ about my script, I would welcome your advice.
#Declare my array and String parameters
$objectCollection = @()
$seperator = "\"
$option = [System.StringSplitOptions]::RemoveEmptyEntries
#Get List of Host Clients from Active Directory
$TPHosted = Get-ADOrganizationalUnit -Filter * -SearchScope Subtree -SearchBase "OU=Hosted,DC=XXXX,DC=local"
foreach ($TPclient in $TPHosted)
{
$CompanyOU = [string]$TPclient.Name
$OUPath = [string]$TPClient.DistinguishedName
$RandomUser = Get-ADUser -Filter * -SearchBase $OUPath -Properties homedirectory | where-object {$_.homedirectory -ne $null} | Sort-Object{Get-Random} | Select -First 1
#Some clients might not have any data on the file server (example...email only). Only create objects for 'hosted' data clients.
if($randomUser.homedirectory)
{
$ClientDrive = [string]$RandomUser.homedirectory
$array = $ClientDrive.Split($seperator,2,$option)
$Server = $array[0]
$properties = @{
Client=$CompanyOU;
Server = $Server
}
$object = New-Object -TypeName PSObject -Property $properties
$objectCollection += $object
}
else
{
#No users in the Client OU have data within hosted enviornment
}
} #End of ForEach TPClient
$objectCollection