Network Driveletters

by Slashj at 2013-02-21 06:00:37

Hi Comm,

So recently i got an task described like this:

"We need to know, which driveletters are used by all Users?"

So my company wants to know which driveletters are used or not used inside the whole company.

I told myself…"This is doable with PoSh so lets do this"

My plan is:

(I should mention that we have an mixed environment -Win7 and WinXP- but our WinXP machines have PoShV2 installed localy)

Write an script that gets the information needed and build it into the logonscript.

The script goes like this:

$username = $env:username
$hostname = $env:computername
Try{
Get-WmiObject -Namespace root\cimv2 -Class win32_logicaldisk -ErrorAction Stop | select -ExpandProperty Deviceid > "\networkpath$username.txt"
}
catch{
echo "Error reading Data on $hostname" >> "\networkpath$username.txt"
}
----------------------
For now i would extend the logonscript.bat with the following line:

"c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe" Pathtoscript\script.ps1

Now i should get an text file created from every user that is loggin in on his machine.

The next step would be to analyze these files with PoSh with another script going like this:

$files = dir C:\Test | select -ExpandProperty name
<#
path to the outputfiles generated from users C:\Test
Content of these files looks like this:
C:
D:
E:
F:
#>
$files | %{
Get-Content "C:\test$($)" | %{
$letter = $

$result = Get-Content "C:\result.txt" | ?{$_ -eq "$letter"}
if(!$result){
Echo "$letter" >> "C:\reports\result.txt"
}
}
}

In the end i have an file containing all the driveletters that are used by our companies users.
--------------------------
I think this way is probably to much and to complicated and thats why im writing this :).

What do you guys think of this?
Is there an easier way to retrieve this information?
Or do you think this will completly run into errors or give me bad results?

Thanks in advance,

BR

Ps: Sorry if im writing this in the wrong forum.
by jonhtyler at 2013-02-21 08:14:08
Hi, one warning I would have is that you have a chance of not getting every user to run your logon script…for example, if you have users that don’t log on for a while. You could also have a situation where someone maps a drive after logging on…that would not be captured either. That being said, the logon script, I believe, will work otherwise.

I would change your processing script a little, for example:

$LettersInUse = @()
if (Test-Path -Path c:\reports\result.txt)
{
$LettersInUse = get-content c:\reports\result.txt
}
get-childitem -Path c:\test -filter .txt | get-content | ?{($_ -notlike "Error") -and ($LettersInUse -notcontains $)} | foreach-object {$LettersInUse = $LettersInUse + $}
$LettersInUse | sort-object | out-file -Path c:\reports\result.txt


This code sets up an object array. It checks to make sure you have a file to read from for initial data, but if not, just moves on. It then gets all of your username.txt files, reads the content from each one, makes sure it doesn’t have an error in it and that the object array doesn’t already contain it. Anything that goes beyond that is a drive letter that is not already in the list, so it adds that letter to the array. Finally, it sorts the letters in the array, and then outputs them back to the original file.
by Slashj at 2013-02-21 08:24:28
Hey there,

Yeah i have it in mind that we wont get every user into it, but i guess it´ll be fine :).

That code looks cool for me, forgot about the "error" lines.

Thx
by coderaven at 2013-02-21 08:26:37
Sorry for the reference, but this looks a little old school. I try to pull live data now days using WMI/CIM. I would recommend using the throttling but your query needs data from 2 classes, LogicalDisk and ComptuerSystem. Here is a rough ad-hoc example of the way I would approach it.

$AllComputers = (Get-ADComputer -Filter * | Select-Object -ExpandProperty Name)
Foreach ($Computer in $AllComputers)
{
$CS = $Null
$LD = $Null
if (Test-Connection -ComputerName $Computer -Count 1 -Quiet)
{
try {
$CS = Get-WMIObject -ComputerName $Computer -Class Win32_ComputerSystem
$LD = Get-WMIObject -ComputerName $Computer -Class Win32_LogicalDisk
foreach ($Disk in $LD)
{ New-Object PSObject -Property @{"Computer"=$Computer,User=$CS.UserName;Letter=$Disk.DeviceID}
} #end try
catch { New-Object PSObject -Property @{"Computer"=$Computer,"User"="Connection Failure";"Letter"=$Null}
else
{New-Object PSObject -Property @{"Computer"=$Computer,User="Offline";Letter=$Null}
}


Here you can save the data for later use and only try to re-query the systems that were currently offline or had an issue. One thing to note is that if you have shared computers you may need to take a different route because different users may have different drives mapped. Using your logon method, would be good if you want to keep collecting the information over a period of time. In my experience, getting 80-90% will give you a great idea of what is going on.
by jonhtyler at 2013-02-21 08:29:40
Hi Allen,

I also thought about the "remote"-ing possibility, however, it will not report on anyone but your (the person running this script) drive letters, and then only if you happen to be logged into the console. See this article that has some more detail on that…http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/46881e57-62a4-446e-af2d-cd2423e7837f/