This blog has moved to http://ThePowerShellGuy.com
Greetings /\/\o\/\/
this Powershell scipt will import the shares from the CSV file created in the first part of this serie :
PowerShell Export Shares and Security info to CSV .
For this example let's asume that we have 2 shares : Foo and Bar
so listing the shares will give this output :
MowPS>gwmi Win32_Share -filter 'type=0'
Name Path Description
---- ---- -----------
Bar C:\Bar
Foo C:\Foo
on both we have everyone read and on the Share Bar I added MOW with Full Control
and did we run the script in the first post in this serie and exported them to a CSV file, the file would look like this :
MowPS>gc ShareInfo.csv
Name,Path,Description,User,Domain,SID,AccessMask,AceFlags,AceType
Bar,C:\Bar,,Everyone,Computer,S-1-1-0,1179817,0,0
Bar,C:\Bar,,Mow,Computer,S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx,2032127,0,0
Foo,C:\Foo,,Everyone,Computer,S-1-1-0,1179817,0,0
we can check the rights by using the FileSystemRights Enum :
MowPS>[System.Security.AccessControl.FileSystemRights]1179817
ReadAndExecute, Synchronize
MowPS>[System.Security.AccessControl.FileSystemRights]2032127
FullControl
(note share security is a bit different from filesystemsecurity so the reading is a bit different
Replace Security on existing share using MSH)
now we want to re-create the shares
I will first show some parts of it from the CommandLine and then show the complete script (the compete script can be pasted to the commandline also) :
first we get the CSV file into an PSObject again
MowPS>$ShareList = Import-Csv ShareInfo.csv
MowPS>$sharelist
Name : Bar
Path : C:\Bar
Description :
User : Everyone
Domain : Computer
SID : S-1-1-0
AccessMask : 1179817
AceFlags : 0
AceType : 0
Name : Bar
Path : C:\Bar
Description :
User : Mow
Domain : Computer
SID : S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx
AccessMask : 2032127
AceFlags : 0
AceType : 0
Name : Foo
Path : C:\Foo
Description :
User : Everyone
Domain : Computer
SID : S-1-1-0
AccessMask : 1179817
AceFlags : 0
AceType : 0
as we only can create the share one time but there could me more entries for a share in the script I loop only trough the shares on the commandline it looks like this :
MowPS>$sharelist | select -unique name,Path,Description
Name Path Description
---- ---- -----------
Bar C:\Bar
Foo C:\Foo
you can see how get a list with every share only one time, so I can loop trough it to make the shares.
for each share in the loop I find only the rows of the second share and I do another loop (on the commandline Example I hardCoded Bar)
MowPS>$sharelist |? {$_.name -eq 'bar'}
Name : Bar
Path : C:\Bar
Description :
User : Everyone
Domain : Computer
SID : S-1-1-0
AccessMask : 1179817
AceFlags : 0
AceType : 0
Name : Bar
Path : C:\Bar
Description :
User : Mow
Domain : Computer
SID : S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx
AccessMask : 2032127
AceFlags : 0
AceType : 0
Next I need to convert the textform SID into a Binary SID again,
therefore we can use the securityidentifier .NET class ( for more info see :
Get Binary SID in MSH (Share Security Update))
an commandline example for one SID :
MowPS>$sharelist[1].sid
S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx
MowPS>$sid = new-object security.principal.securityidentifier(($sharelist[1].sid))
MowPS>[byte[]]$ba = ,0 * $sid.BinaryLength
MowPS>$sid.GetBinaryForm($ba,0)
MowPS>$sid fl
BinaryLength : 28
AccountDomainSid : S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx
Value : S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx
MowPS>$ba
1
5
0
0
0
0
0
5
21
...
...
(there are also examples on my blog to translate the SID object to a user, try a search for SID on my blog for this)
the making of the trustee and ACE'es are the same as in the change share security sample so I will not further go into it here,
only you may note that I do this for the name property only :
$Trustee.get_Properties()['name'].set_Value($_.domain)
this is becouse there is a AliasProperty Name Defined that overrules the Original Name property of the win32_trustee Class in the typedata of PowerShell RC1, I will file this as a Bug on Connect.
the calling of the create method I did from an template I did create with the get-WmiMethodHelp script from this post :
MSH get-WmiMethodHelp function Update 3 and did fill in.
note the use of $sd.PsObject.BaseObject
(if you forget this PowerShell will give a confusing error)The Complete script looks like this :
# ImportShares.ps1
# This script will Import the Shares from a CSV file
# made by ExportShares.ps1 complete with securityInfo
#
# /\/\o\/\/ 2006
# http://mow001.blogspot.com
# Import the CSV file
$ShareList = Import-Csv ShareInfo.csv
# get the Unique Shares
$sharelist | select -unique name,Path,Description |% {
$name = $_.name
$path = $_.Path
$description = $_.Description
"Processing : $name $path $description"
$sd = new-object system.management.managementclass Win32_SecurityDescriptor
$sd.DACL = @()
$ace = new-object system.management.managementclass Win32_ace
$Trustee = new-object system.management.managementclass win32_trustee
# Get all records in CSV file for the current share
$sharelist |? {$_.name -eq $name} |% {
# Convert SID to Binary version :
$sid = new-object security.principal.securityidentifier($_.sid)
[byte[]]$ba = ,0 * $sid.BinaryLength
$sid.GetBinaryForm($ba,0)
# Make Trustee Object
$Trustee.Domain = $_.Domain
$Trustee.get_Properties()['name'].set_Value($_.domain)
$Trustee.SID = $ba
# Make ACE Object
$ace.AccessMask = $_.AccessMask
$ace.AceType = $_.AceType
$ace.AceFlags = $_.AceFlags
$ace.trustee = $trustee.psobject.baseobject
# Add ACE to the DACL
$sd.DACL += $ACE.psObject.baseobject
}
$MC = new-object system.management.ManagementClass win32_share
$InParams = $mc.GetMethodParameters('Create')
# fill Parameters
$InParams["Access"] = $sd.PsObject.BaseObject
$InParams["Description"] = $_.Description
$InParams["Name"] = $_.name
$InParams["Password"] = [string]
$InParams["Path"] = $_.Path
$InParams["Type"] = 0
$R = $mc.InvokeMethod('Create', $inParams, $Null)
"Result : $($R.ReturnValue)"
}
And we can use it like this :
MowPS>gwmi win32_share -filter "type = 0"
Name Path Description
---- ---- -----------
Bar C:\Bar
Foo C:\Foo
#delete shares
MowPS> ( gwmi win32_share -filter "name = 'foo'").delete()
MowPS> ( gwmi win32_share -filter "name = 'bar'").delete()
# shares gone
MowPS>gwmi win32_share -filter "type = 0"
#import shares
MowPS>.\ImportShares.ps1
Processing : Bar C:\Bar
Result : 0
Processing : Foo C:\Foo
Result : 0
# shares back
MowPS>gwmi win32_share -filter "type = 0"
Name Path Description
---- ---- -----------
Bar C:\Bar
Foo C:\Foo
# if shares are there we get an error 22
MowPS>.\ImportShares.ps1
Processing : Bar C:\Bar
Result : 22
Processing : Foo C:\Foo
Result : 22
# check the security :
MowPS>$shareSec = gwmi Win32_LogicalShareSecuritySetting -filter "name='bar'"
MowPS>$shareSec.invokeMethod('GetSecurityDescriptor',$null,$null).descriptor.dacl % {
>> $_ select @{e={$share.name};n='Name'},
>> @{e={$share.Path};n='Path'},
>> @{e={$share.Description};n='Description'},
>> AccessMask,
>> AceFlags,
>> AceType,
>> @{e={$_.trustee.Name};n='User'},
>> @{e={$_.trustee.Domain};n='Domain'},
>> @{e={$_.trustee.SIDString};n='SID'}
>> }
>>
Name : Foo
Path : C:\Foo
Description :
AccessMask : 1179817
AceFlags : 0
AceType : 0
User : Everyone
Domain : Computer
SID : S-1-1-0
Name : Foo
Path : C:\Foo
Description :
AccessMask : 2032127
AceFlags : 0
AceType : 0
User : Mow
Domain : Computer
SID : S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx
# and Yep this looks right, the seurity is back also.
you can see the shares are recreated with the right securitym and a return value is returned to check if it want OK (a 0 means OK a 22 share does exist allready).
if you want to know the other returnvalues you can look at the get-WmiMethodHelp script output also :
MowPS>get-WmiMethodhelp win32_share create
win32_share : create :
The Create method initiates sharing for a server resource. Only members of the Administrators or Account Operators local group or those wit
h Communication, Print, or Server operator group membership can successfully execute Create. The Print operator can add only printer queues
. The Communication operator can add only communication device queues. The method returns an integer value that can be interpretted as foll
ows:
0 - Successful completion.
2 - The user does not have access to the requested information.
8 - Unknown failure.
9 - The character or file system name is invalid.
10 - The value specified for the level parameter is invalid.
21 - The specified parameter is invalid.
22 - The share name is already in use on this server.
23 - The operation is invalid for a redirected resource. The specified device name is assigned to a shared resource.
24 - The device or directory does not exist.
25 - The share name does not exist.
Other - For integer values other than those listed above, refer to Win32 error code documentation.
create Parameters :
...
<snap>
Enjoy,
Greetings /\/\o\/\/
Tags : Monad msh PowerShellPS. as Blogger had problems and my first post failed my post is messed up by BLogger,
so the formatting is messed up and you may miss some pipeline symbols (and and of lines when pasting, sorry for that,
but I RePasted the complete script again into the post so that should not give problems when pasted in the the powerShell