PowerShell for Windows Admins


April 21, 2010  2:30 PM

Shares:Security

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

In the previous post we saw how to get the Access Mask for the current user for a particular share.  It would be better if we could dump the information for all shares and all security access in one go.

We need to use Win32_LogicalAccess

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
function Get-ShareSecurity {

    Get-WmiObject -Class Win32_LogicalShareAccess |
    foreach {
       $name = ($_.SecuritySetting -split “=”)[1]
       $sid = (($_.Trustee -split “=”)[1]).Replace(‘”‘,)
       $AccessMask = $_.AccessMask
      
       $query =  “ASSOCIATORS OF {Win32_SID.SID='” `
       + $sid + “‘} WHERE ResultClass=Win32_SystemAccount”
      
       $trustee = Get-WmiObject -Query $query 
      
       if($trustee -eq $null){
            $query =  “ASSOCIATORS OF {Win32_SID.SID='” `
            + $sid + “‘} WHERE ResultClass=Win32_UserAccount”
            #$query
            $trustee = Get-WmiObject -Query $query 
       }
      
       if($trustee -eq $null){
            $query =  “ASSOCIATORS OF {Win32_SID.SID='” `
            + $sid + “‘} WHERE ResultClass=Win32_Group”
             $trustee = Get-WmiObject -Query $query 
       }
      
       “`nSHARE: $name USER: $($trustee.Caption) RIGHTS:”
       ## now we need to unravel the rights
        $mask.GetEnumerator()| sort Key | 
        foreach {
            if ($AccessMask -band $_.key){“$($mask[$($_.key)])”}
        }
      
    }
}

 

It returns an object for each share for each user or group that gets access to the share.

For each object returned we get the share name, the SID and the access mask. We use the SID to find the user, system or group account that has that access and then dump out the rights as we saw last time

April 14, 2010  7:08 AM

Shares: Access mask

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The access mask controls what you can do i.e. what rights you have. We can use the GetAccessMask method to find the access mask but all we get back is a number we need unravel it. The number id a bit mask with the following values assigned

$mask = DATA {
ConvertFrom-StringData -StringData @’
1 = Grants the right to read data from the file. For a directory, this value grants the right to list the contents of the directory.
2 = Grants the right to write data to the file. For a directory, this value grants the right to create a file in the directory.
4 = Grants the right to append data to the file. For a directory, this value grants the right to create a subdirectory.
8 = Grants the right to read extended attributes.
16 = Grants the right to write extended attributes.
32 = Grants the right to execute a file. For a directory, the directory can be traversed.
64 = Grants the right to delete a directory and all of the files it contains (its children), even if the files are read-only.
128 = Grants the right to read file attributes.
256 = Grants the right to change file attributes.
65536 = Grants delete access.
131072 = Grants read access to the security descriptor and owner.
262144 = Grants write access to the discretionary access control list (DACL).
524288 = Assigns the write owner.
1048576 = Synchronizes access and allows a process to wait for an object to enter the signaled state.
‘@
}

We can use the mask like this

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
function Get-ShareAccessMask {
[CmdletBinding(SupportsShouldProcess=$True)]
param (
    [string]$name
)   
    $share = Get-WmiObject -Class Win32_Share -Filter "Name=’$name’" 
$ret = (Invoke-WmiMethod -InputObject $share -Name GetAccessMask).ReturnValue
   
    ## now we need to unravel the rights
    $mask.GetEnumerator()| sort Key | foreach {
       if ($ret -band $_.key){
            "$($mask[$($_.key)])"
        }
   
    }
}   

 

We use invoke-wmimethod to get the mask and then compare the keys of our hash table against the access mask.

This returns the mask for the person running the script not the whole mask.

Technorati Tags: ,,,


April 12, 2010  9:58 AM

Powershell User Group Live Meeting: Modules

Richard Siddaway Richard Siddaway Profile: Richard Siddaway


When: Tuesday, Apr 20, 2010 7:30 PM (BST)


Where: Virtual

*~*~*~*~*~*~*~*~*~*

Notes

We will cover the new module functionality introduced with PowerShell v2 with a biref look at some of the functionality available in Windows 7/Windows 2008 R2


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: B3FG29
    Entry Code: Zft%D4B7H
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.


April 9, 2010  12:42 PM

PowerShell for DNS

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve blogged on a number of occasions on how to use the DNS WMI provider.

Life just got easier with the release of DnsShell.  Its a PowerShell 2.0 module containing cmdlets for working with DNS.

Underneath the covers there is a lot of WMI involved.

The module is still a work in progress but already includes useful functionality.  I’ll be giving it a try out soon.

The module can be down loaded from http://code.msdn.microsoft.com/dnsshell

Technorati Tags: ,,


April 2, 2010  11:14 AM

Shares: Discovering

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

As I said last time I’ve modified the Get-Share function to accept a share name.

001
002
003
004
005
006
007
function Get-Share {
param (
    [string]$name
)   
    if (!$name) {Get-WmiObject -Class Win32_Share}
    else {Get-WmiObject -Class Win32_Share -Filter “Name=’$name'”}
}

if a name isn’t provided that all shares are returned.  If we supply a name only that share is returned. In either case we can put the object onto the pipeline and perform further processing.

Get-Share | ft name, maximumallowed, description

Get-Share -name test1 | fl name, maximumallowed, description


April 2, 2010  11:07 AM

Shares: Modifying

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

So far we’ve seen how to discover and create shares.  How do we alter a share?

When we created a share we supplied a number of pieces of information:

  1. folder path
  2. name
  3. type – disk share
  4. maximum number of connections
  5. description

The last two and the permissions mask are the ones we want to alter

001
002
003
004
005
006
007
008
009
010
011
012
013
014
function Set-Share {
[CmdletBinding(SupportsShouldProcess=$True)]
param (
    [string]$name,
    [int]$maxcon,
    [string]$desc
)   
    $share = Get-WmiObject -Class Win32_Share -Filter "Name=’$name’" 
    if (!$maxcon){$maxcon = $share.MaximumAllowed }
    if (!$desc){$desc = $share.Description}
   
    $share.SetShareInfo($maxcon, $desc, $null)

}

Use the share name, maximum connections and description as parameters. If either the number of connections or the description is not set we use the current value.

A call to the SetShareInfo method is used to perform the change.  The $null value at the end is the access mask which we will see how to change later.

The function is used like this

Get-Share -name test1 | fl name, maximumallowed, description
Set-Share -name test1 -desc "Changed"
Get-Share -name test1 | fl name, maximumallowed, description

Set-Share -name test1 -maxcon 25
Get-Share -name test1 | fl name, maximumallowed, description

Set-Share -name test1 -maxcon 25 -desc "New Description"
Get-Share -name test1 | fl name, maximumallowed, description

I’ve altered my Get-Share function so that it becomes capable of returning a single share.  I’ll post that change next


April 1, 2010  12:48 PM

MVP re-award

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I had a very nice email from the Microsoft MVP award program today informing me that I had been re-awarded as a PowerShell MVP.

Its a great honour to receive the MVP award and thank you to Microsoft for the award and to the PowerShell community for supporting my efforts.


March 30, 2010  2:34 PM

Shares: Creating III

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

In a previous post

https://itknowledgeexchange.techtarget.com/powershell/shares-creating-ii/

we looked at creating a file share. This function can be expanded to test for the existence of the folder and if we succeed or not.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
function New-Share {
[CmdletBinding(SupportsShouldProcess=$True)]
param (
    [string]$path,
    [string]$name,
    [int][ValidateRange(0,2)]$type,
    [int]$maxcon,
    [string]$desc
)

$fail = DATA {
ConvertFrom-StringData -StringData @’
0 = Success
2 = Access Denied
8 = Unknown Failure
9 = Invalid Name
10 = Invalid Level
21 = Invalid Parameter
22 = Duplicate Share
23 = Redirected Path
24 = Unknown Device or Directory
25 = Net Name Not Found
‘@

}

    if (!(Test-Path -Path $path)){Throw “Folder does not exist”}
    $s = [WmiClass]“Win32_Share” 
    $ret = $s.Create($path, $name, $type, $maxcon, $desc)
    if ($ret.ReturnValue -ne 0){
        Write-Host “Share $name was not created”
        Write-Host “Failure reason: $($fail[“$($ret.ReturnValue)”])”
    }
    else {Write-Host “Share $name was created”}
}

 

 

We add a hash table of the return codes from the create method. A simple Test-Path enables us to determine if the share exists.

We can test the return code and if the value is zero state the creation succeeded otherwise we report failure and the reason.

PS> New-Share -path c:\share1 -name Test1 -type 0 -maxcon $null -desc “Test share 1 from module”
Share Test1 was not created
Failure reason: Duplicate Share

Technorati Tags: ,


March 24, 2010  1:20 PM

Scripting Games 2010

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Don’t expect to be anywhere but in front of your computer between 26 April and 7 May.  Why? because the 2010 Scripting Games are happening.

The usual 10 events with beginners and advanced versions.

A whole bunch of expert commentators – including me.

For more information and a few hints on things that could be useful see http://blogs.technet.com/heyscriptingguy/archive/2010/03/21/hey-scripting-guy-march-21-2010.aspx


March 24, 2010  1:19 PM

Book Review: Windows PowerShell 2.0 best practices

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve published a review of the book here

http://msmvps.com/blogs/richardsiddaway/archive/2010/03/23/book-review-windows-powershell-2-0-best-practices.aspx

There are some WMI techniques that may be of interest to readers of this blog

Technorati Tags: ,


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: