This blog has moved to http://ThePowerShellGuy.com
Greetings /\/\o\/\/
IF you have a directory shared and you delete the Directory from a Command prompt or script, the share will stay behind in the Registry, this is called an Orphaned Share.
(if you do this from the Explorer you get a message that it is shared, and the share will be removed, but not if this is done from the commandline)
so if you remove a directory that is shared, the value in the registry will remain and the server service will try to recreate them whan the computer is restarted.
if you restart the computer you get errormessages like this in the Eventviewer :
Event Type: Error
Event Source: Server
Event Category: None
Event ID: 2511
Date: 19-12-2005
Time: 7:22:22
User: N/A
Computer: ComputerName
Description:
The server service was unable to recreate the share wees$ because the directory c:\wees no longer exists.
This Script will Check and clean those "Orphaned Shares" on the local or on a remote computer.
To be a bit more safe, I set the ErrorActionPreference to Stop and the script will only check and not change anything if the DoChange parameter is not set to $true.
Ofcourse it's still a good Idea to backup the registry key first.
As I will not give the standard disclaimer, but it's the registry we are changing.
and as all the scripts on this blog, it's an example not a production script, actualy I DID run this agains a production server, to remove a lot of event-entries at boot ;-), but I backuped and double checked everything before running and did -
ofcourse, as I made it - know exactly what the script did, but i would not give this to someone to do regular cleaning, that would require a "production-script" that is completely tested, so be sure to know the script before running with $true parameters ;-).
OK, enough warnings, let's go on,
the script works like this :
(Note, I run it 3 times, first to check, then to change (the counter will not change, as it counted the old data, then to check again.)# Check Mode
.\OrphanShares.msh ComputerName
public$ Exists
wees$ is an Orphan
...
Orphan :
323
Existing :
1931
# Change Mode (DoChange Parameter given,Orphan shares will be removed)
.\OrphanShares.msh ComputerName $true
public$ Exists
wees$ is an Orphan
wees$ Deleted !!
Orphan :
323
Existing :
1931
# Third Run (Check Mode again)
.\OrphanShares.msh ComputerName
public$ Exists
...
Orphan :
Existing :
1931
first, I checked the server (remote) for "Orphaned shares", I did cut out most of the output but there where 323 orphaned shares (I knew as the server had rebooted this morning giving me all the EventId 2511 Errors in the eventlog, what started this all ;-) )
then I did do the same with DoChange set to $true. (note that the count is not updated yet)
and then I check again, ... Yes they are gone ..
As you can see we have 323 Orphan shares less now
(And "more important" the "annoying" 323 matching event-entries ;-))and then the script :
1 # OrphanShares.msh
2 # Checks / Removes Orphan Shares
3 # /\/\o\/\/ 2005
4
5 param (
6 [string] $Computer = ".",
7 [bool] $DoChange = $false
8 )
9
10 # to be safe stop at errors.
11 $ErrorActionPreference = "stop"
12
13 # Connect to registry
14
15 $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
16 $key = $Reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\LanmanServer\Shares", $True)
17
18 # get shares in Registry :
19
20 $Regshares = $Key.GetValueNames()
21
22 # get Existing shares :
23
24 $shares = @();get-WMIObject -computer $Computer win32_share | foreach {$shares += $_.name}
25
26 # Compare the Lists :
27
28 $RegShares | foreach {
29 if ($shares -eq $_) {
30 "$_ Exists"
31 }Else {
32 "$_ is an Orphan"
33 # Only if DoChange is True Delete The Orphan Share
34 if ($Dochange) {$Key.DeleteValue($_);"$_ Deleted !!"}
35 }
36 }
37
38 # show some statistics :
39
40 "Orphan : ";($RegShares | foreach {"$_ $($shares -eq $_)"} | findstr "False" | measure-object).count
41 "Existing : ";($RegShares | foreach {"$_ $($shares -eq $_)"} | findstr "True" | measure-object).count
Line 15 Connects to the remote registry
Line 16 gets the LanmanServer Shares key
line 20 Gets all the ShareNames into the $RegShares array
line 24 Does the same but then with WMI that will give only the shares that realy exist on the system, these Sharenames go into the $shares Array.
in the loop starting on Line 28, 2 things are interesting :
Line 29 : if ($shares -eq $_)
as $_is the Current ShareName from $regShares the -eq will check against the WHOLE array, so we don't need an extra loop here.
Line 34 : we will only delete the (current)share from the registry as the -Dochange parameter is set to $true.
line 40 + 41 give the statistics the statistic checks do an extra loop, as I did not bother about performance to much, but this could be better added to the main loop.
this started as a 5 line commandline history that I copied in notepad while doing this at work (good excuse to use Monad.. ehh.. I mean WMI and the registry).
I did the action just by doing the actions on the commandline..
Use the history buffer till the command does exactly what I want...
paste the command in notepad...
so at the end of the action you have the script as result, and while working you can just copy parts of the textfile into the Commandline interface, to run parts of the script (to be), for example to reset things.
I just love this way of working.. that's what makes Monad so powerfull and quick.
gr /\/\o\/\/