/\/\o\/\/ PowerShelled

This blog has moved to http://ThePowerShellGuy.com Greetings /\/\o\/\/
$AtomFeed = ("Atom.xml")
$PreviousItems = (" An other PowerShell Blog is born "," Windows PowerShell: TFM "," PowerShell Export Shares and Security info to CSV "," powershell (Monad) Home on computerperformance.co.uk "," PowerShell in Action "," PowerShell out-PropertyGrid (MSH view-Object) "," PowerShell AD site Finder "," PowerShell and SMS 2003 "," Upgrading MSH, My first Windows PowerShell Commands "," Some more Windows PowerShell Links and info. "," ")

Tuesday, May 02, 2006

 


PowerShell Import Shares and Security info From CSV



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 :

PS. 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


Comments:
Anonymous Anonymous
MOW I have been following your work on newsgroup and on this blog. I am just starting with PS and the 2 security cmdlets look great. My question is how difficult to modify to export security on a folder and then reverse; and more complicatedly to recurse?
Pete Gomersall
 
Blogger /\/\o\/\/
Thanks for the Comment,
and sorry for the late reaction.

as you can see in the NG the Directory security works about the same as the share permisions.

there are just a couple more thinks to reconcider :

Inheritance, recursion ans special rights.

but it's also doable

gr /\/\o\/\/
gr /\/\o\/\/
 
Blogger /\/\o\/\/
I hope this will help:

http://mow001.blogspot.com/2006/05/powershell-import-and-export.html

gr /\/\o\/\/
 
Post a Comment



<< Home

Archives

October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   April 2006   May 2006   June 2006   July 2006   August 2006   September 2006   October 2006   November 2006   December 2006  

$Links = ("PowerShell RC1 Docs"," PowerShell RC1 X86"," PowerShell RC1 X64"," Monad GettingStarted guide"," Monad Progamming Guide"," Monad SDK"," Monad videos on Channel 9"," MSH Community Workspace"," scripts.readify.net "," MonadSource"," www.reskit.net"," PowerShell Blog"," Under The Stairs"," computerperformance powershell Home"," proudlyserving"," MSH on wikipedia"," MSHWiki Channel 9"," Keith Hill's Blog"," Precision Computing"," PowerShell for fun"," MSH Memo (Japanese)"," monadblog")

find-blog -about "PowerShell","Monad" | out-Technorati.
find-blog -contains "","" | out-Technorati.
Google
 
Web mow001.blogspot.com

This page is powered by Blogger. Isn't yours?