Jump to content

Recommended Posts

Posted

Currently I have the share for user areas at the containing folder level - so \\server\$\%username% Now, mainly due to having to do things the way our new MAT wants us to, I need to set the share at the username level - \\server\%username%$.

 

Is there a simple script I can run that will add all the new shares, but keep the existing ones in place until we switch GPOs across?

Posted (edited)
\\server\%username%$.

 

I have to ask but are you sure that's the path they want? (Edit - Just to clarify, the path of the "share" not the "mapping"?) As it's an extremely poor way of doing it as you'd have to have one share per account? :s Also meaning manually setting permissions on every single share to each person, rather than inheriting them etc.

 

I could understand them wanting all users in one share as such, but not that way. (It would require custom scripts really)

 

Steve

Edited by Steve21
Posted
As it's an extremely poor way of doing it as you'd have to have one share per account? :s Also meaning manually setting permissions on every single share to each person, rather than inheriting them etc.

Scuse my ignorance, but with (say) an individuals network drive, how can you avoid creating a share per user?

Posted

You'd have to create a custom script that's pulling each name of the folder through then as obviously the %username% part of it won't work on shares as it doesn't exist to the "file-system" (That is assuming each folder is the name of the username?)

 

 

Steve

Posted
Scuse my ignorance, but with (say) an individuals network drive, how can you avoid creating a share per user?

 

You create the share as say "Users" So \\\blah.sch.uk\Users$ then use their individual folder that gets created on logon as the barrier for permissions. Therefore everyone is mapped to one share and uses the normal %username% variable in the mapping. e.g. N:\ maps to \\blah.sch.uk\Users$\%username% only one share required that way.

 

Steve

 

- - - Updated - - -

 

I would seriously consider using Access Based Enumeration instead. It will be easier to set up and easier to manage.

 

Access-Based Enumeration in Windows Server - Aaron Parker

 

If each usergroup is in their own folder that wouldn't work though, as you'd still have 5 shares (if 5 yeargroups etc) Unless I'm missing something with that way?

 

Steve

  • Thanks 1
Posted

You can do it in powershell. The function I have for creating shares :

 

$fileserver = "OurServer"
$ServBase = "D:\users" 


# ---------------------------------------------------------------------------
# Create a share on the (presumed) remote fileserver and set full control 
# to everyone (control access via folder permissions)
# ---------------------------------------------------------------------------
function CreateShare2 {

   # cribbed from 
   # http://social.technet.microsoft.com/Forums/scriptcenter/en-US/6aa558a6-f8b4-4cb5-bbb3-76eec9805681/powershell-remote-server-set-share-permissions-to-everyone-full-control

   Param ([string]$UserName, [string]$Target )

   $Computer = $fileserver
   $Class = "Win32_Share"
   $Method = "Create"
   $name = "$UserName`$"
   $path = $ServBase + $UserName
   
   $description = "AutoCreated"
   $sd = ([WMIClass] "\\$Computer\root\cimv2:Win32_SecurityDescriptor").CreateInstance()
   $ACE = ([WMIClass] "\\$Computer\root\cimv2:Win32_ACE").CreateInstance()
   $Trustee = ([WMIClass] "\\$Computer\root\cimv2:Win32_Trustee").CreateInstance()
   $Trustee.Name = "EVERYONE"
   $Trustee.Domain = $Null
   $Trustee.SID = @(1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0)
   $ace.AccessMask = 2032127
   $ace.AceFlags = 3
   $ace.AceType = 0
   $ACE.Trustee = $Trustee
   $sd.DACL += $ACE.psObject.baseobject
   $mc = [WmiClass]"\\$Computer\ROOT\CIMV2:$Class"
   $InParams = $mc.psbase.GetMethodParameters($Method)
   $InParams.Access = $sd
   $InParams.Description = $description
   $InParams.MaximumAllowed = $Null
   $InParams.Name = $name
   $InParams.Password = $Null
   $InParams.Path = $path
   $InParams.Type = [uint32]0
   $R = $mc.PSBase.InvokeMethod($Method, $InParams, $Null)
   
   switch ($($R.ReturnValue))
   {
       0 {$ret="Share:$name Path:$path Result:Success"; break}
       2 {$ret="Share:$name Path:$path Result:Access Denied";break}
       8 {$ret="Share:$name Path:$path Result:Unknown Failure";break}
       9 {$ret="Share:$name Path:$path Result:Invalid Name";break}
       10 {$ret="Share:$name Path:$path Result:Invalid Level";break}
       21 {$ret="Share:$name Path:$path Result:Invalid Parameter";break}
       22 {$ret="Share:$name Path:$path Result:Duplicate Share";break}
       23 {$ret="Share:$name Path:$path Result:Reedirected Path";break}
       24 {$ret="Share:$name Path:$path Result:Unknown Device or Directory";break}
       25 {$ret="Share:$name Path:$path Result:Network Name Not Found";break}
       default {$ret="Share:$name Path:$path Result:*** Unknown Error ***";break}
   }    
   $ret
}
# ---------------------------------------------------------------------------

 

So I'd prep a CSV with the info and then for each item in the csv, just call that function passing the username and the target (\\$fileserver\) which would create the share.

  • Thanks 1
Posted
I have always shared out the root folder and then the individuals have permissions only to their folders within that. Sharing out individual folders is unnecessary in 99% of occasions.
Posted
You create the share as say "Users" So \\\blah.sch.uk\Users$ then use their individual folder that gets created on logon as the barrier for permissions. Therefore everyone is mapped to one share and uses the normal %username% variable in the mapping. e.g. N:\ maps to \\blah.sch.uk\Users$\%username% only one share required that way.

 

Steve

 

- - - Updated - - -

 

 

 

If each usergroup is in their own folder that wouldn't work though, as you'd still have 5 shares (if 5 yeargroups etc) Unless I'm missing something with that way?

 

Steve

 

 

Sorry if i've misunderstood but does he not really have what you've suggested? apart from the fact hes got year of entry rather than users as a whole?

Posted
I agree with everyone who says to share out the root folder - I've done it that way for years. However, I have to do as instructed.
Posted
My powershell is sadly lacking, but I can't find any reference in that script to a csv - so does it need a specific name, or to be in a specific location?
Posted (edited)
My powershell is sadly lacking, but I can't find any reference in that script to a csv - so does it need a specific name, or to be in a specific location?

 

Sorry, I didn't supply the complete code you need so no, that is not there! It will just be a loop, something like :

 

$infile = import-csv ""

foreach $user in $infile {
  CreateShare2 $user.username ""
}

 

(sorry, am typing this in away from my main PC so can't actually test at the moment).

Edited by pcstru
Posted

No the first bit of code was a function. The whole thing would be :

 

$fileserver = ""               # Set for your situation
$ServBase = "D:\users"                     #           ''


# ---------------------------------------------------------------------------
# Create a share on the (presumed) remote fileserver and set full control 
# to everyone (control access via folder permissions)
# ---------------------------------------------------------------------------
function CreateShare2 {

   # cribbed from 
   # http://social.technet.microsoft.com/Forums/scriptcenter/en-US/6aa558a6-f8b4-4cb5-bbb3-76eec9805681/powershell-remote-server-set-share-permissions-to-everyone-full-control

   Param ([string]$UserName, [string]$Target )

   $Computer = $fileserver
   $Class = "Win32_Share"
   $Method = "Create"
   $name = "$UserName`$"
   $path = $ServBase + $UserName
   
   $description = "AutoCreated"
   $sd = ([WMIClass] "\\$Computer\root\cimv2:Win32_SecurityDescriptor").CreateInstance()
   $ACE = ([WMIClass] "\\$Computer\root\cimv2:Win32_ACE").CreateInstance()
   $Trustee = ([WMIClass] "\\$Computer\root\cimv2:Win32_Trustee").CreateInstance()
   $Trustee.Name = "EVERYONE"
   $Trustee.Domain = $Null
   $Trustee.SID = @(1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0)
   $ace.AccessMask = 2032127
   $ace.AceFlags = 3
   $ace.AceType = 0
   $ACE.Trustee = $Trustee
   $sd.DACL += $ACE.psObject.baseobject
   $mc = [WmiClass]"\\$Computer\ROOT\CIMV2:$Class"
   $InParams = $mc.psbase.GetMethodParameters($Method)
   $InParams.Access = $sd
   $InParams.Description = $description
   $InParams.MaximumAllowed = $Null
   $InParams.Name = $name
   $InParams.Password = $Null
   $InParams.Path = $path
   $InParams.Type = [uint32]0
   $R = $mc.PSBase.InvokeMethod($Method, $InParams, $Null)
   
   switch ($($R.ReturnValue))
   {
       0 {$ret="Share:$name Path:$path Result:Success"; break}
       2 {$ret="Share:$name Path:$path Result:Access Denied";break}
       8 {$ret="Share:$name Path:$path Result:Unknown Failure";break}
       9 {$ret="Share:$name Path:$path Result:Invalid Name";break}
       10 {$ret="Share:$name Path:$path Result:Invalid Level";break}
       21 {$ret="Share:$name Path:$path Result:Invalid Parameter";break}
       22 {$ret="Share:$name Path:$path Result:Duplicate Share";break}
       23 {$ret="Share:$name Path:$path Result:Reedirected Path";break}
       24 {$ret="Share:$name Path:$path Result:Unknown Device or Directory";break}
       25 {$ret="Share:$name Path:$path Result:Network Name Not Found";break}
       default {$ret="Share:$name Path:$path Result:*** Unknown Error ***";break}
   }    
   $ret
}
# ---------------------------------------------------------------------------



$infile = import-csv ""

foreach $user in $infile {
  CreateShare2 $user.username ""
}

 

You can hard code "target" if they are all the same path on the server (target is the path as seen from the server). Your CSV would then just be the list of users.

  • Thanks 2
Posted

The following will share a folder with its current name with a $ on the end.

FOR /D %%G IN (*.*) DO NET SHARE %%G$=%CD%\%%G /GRANT:Everyone,FULL

 

Save as a batch in the root and run and all folders will be shared.

 

Not sure if it breaks original shares though!

  • Thanks 2
Posted
I must be doing something wrong. When I run that script I get the root folder shared as $, then powershell just reports duplicate share.
Posted
The following will share a folder with its current name with a $ on the end.

FOR /D %%G IN (*.*) DO NET SHARE %%G$=%CD%\%%G /GRANT:Everyone,FULL

 

Save as a batch in the root and run and all folders will be shared.

 

Not sure if it breaks original shares though!

Very neat solution.

Posted
Yes, the userfolders have documents within them.

 

A folder called documents - i.e in AD you will set the documents to map to \\server\share$\Documents?

Posted
I won't take credit as I didn't write it but found it many years ago and works a treat since

I'm obviously becoming too programmed by powershell and neglecting sometimes simpler, more elegant solutions. A bit like as they say, when all you have is a hammer, every problem looks like a nail!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...