PowerShell for Windows Admins


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

http://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: ,


March 21, 2010  7:22 AM

Shares: Creating II

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Now we have seen how to create a share lets extend the script a bit.  This is how a lot of my scripts get developed.  I need to solve a particular problem so I write a script to do that task.  While I’m writing I try to see how I can make the script generic. Sometimes the script is written immediately to solve the generic problem and other times I have to solve the immediate problem and go back to the generic bit later.

001
002
003
004
005
006
007
008
009
010
011
012
function New-Share {
[CmdletBinding(SupportsShouldProcess=$True)]
param (
    [string]$path,
    [string]$name,
    [int][ValidateRange(0,2)]$type,
    [int]$maxcon,
    [string]$desc
)
    $s = [WmiClass]"Win32_Share" 
        $s.Create($path, $name, $type, $maxcon, $desc)
}

We take our earlier script and create a function. This forms part of my module for working with the file system.

I’m creating it as an advanced function so I can use the –whatif parameters later.  The function takes a set of parameters and creates the share.

Its used like this

New-Share -path c:\share1 -name Test1 -type 0 -maxcon $null -desc "Test share 1 from module"

Next stage is to add the code to test the existence of the folder and to check that the share creates properly

Technorati Tags: ,


March 12, 2010  4:06 PM

Shares: Creating I

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

we’ve seen a few things we can do with shares – its time to look at creating them. A simple share craetion script will look like this

001
002
003
004
005
006
New-Item -Path c:\ -Name share1 -ItemType Directory
New-Item -Path c:\share1 -Name shareA -ItemType Directory
New-Item -Path c:\share1 -Name shareB -ItemType Directory

$s = [WmiClass]"Win32_Share"
$s.Create("c:\share1", "Test1", 0, $null, "Test share1")

We create some folders in a hierarchy with New-Item and then create an instance of the Win32_Share class using the [WmiClass] type accelerator.

We can then call the create method. The parameters are:

  • folder path
  • share name
  • share type – 0 = disk share
  • maximum connections allowed – $null means unlimited
  • description

This sets default permissions on the share

Technorati Tags: ,


March 7, 2010  5:23 AM

Shares: Understanding the Access Mask

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

We saw earlier that the access mask was returned as a number.  We need to understand what that number means.

NOTE – BEFORE RUNNING THE SCRIPT ENSURE LINE 16 AND 17 ARE COMBINED.  THEY ARE SPLIT HERE TO FIT THE LISTING INTO THE DISPLAY WIDTH.  THE LINE SHOULD BE CONTINUOUS AND READ

1048576 =  Synchronizes access, allows a process to wait for an object to enter the signaled state.

 

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
$acmsk = DATA {
ConvertFrom-StringData -StringData @’
1 = Read/List
2 = Write/Create File
4 = Append/Create Subdirectory
8 = Read extended attributes.
16 = Write extended attributes.
32 = Execute file/Traverse directory
64 = Delete directory
128 = Read file attributes.
256 = Change file attributes.
65536 = Delete
131072 = Read access to the security descriptor and owner.
262144 = Write access to the discretionary access control list (DACL).
524288 = Assigns the write owner.
1048576 = Synchronizes access, allows a process to wait
for an object to enter the signaled state.
‘@

}

$flags = @(1,2,4,8,16,32,64,128,256,65536,131072,262144,524288,1048576)

$share = Get-WmiObject -Class Win32_Share -Filter "Name=’Test’"
$mask = Invoke-WmiMethod -InputObject $share -Name GetAccessMask

foreach ($flag in $flags){

    if ($mask.ReturnValue -band $flag) {
        Write-Host $acmsk["$($flag)"]
    }

}

 

The Access Mask is a bit mask that is used to determine which permissions have been granted. The various flags are defined in hash table, In this example I decided to used Get-WmiObject to retrieve the share and then use Invoke-WmiMethod to run the getAccessMask method. In PowerShell v1 we could have run

$mask = $share.GetAccessMask()

Once we have the mask we do a bitwise AND against the mask to determine if each permission has been granted.

Technorati Tags: ,,


March 6, 2010  6:06 AM

Share Type

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

One other point we need to cover is the type of share.  We have a number of choices as shown in the script.  The Type property has to be converted from a number to an understandable value – unless you want to learn the share types off by heart.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
$shtyp = DATA {
ConvertFrom-StringData -StringData @’
0 = Disk Drive
1= Print Queue
2 = Device
3 = IPC
2147483648 = Disk Drive Admin
2147483649 = Print Queue Admin
2147483650 = Device Admin
2147483651= IPC Admin
‘@

}

Get-WmiObject -Class Win32_Share | 
select Name, Path, Description,
@{Name="ShareType"; Expression = {$shtyp["$($_.Type)"]}}

A calculated field can be used to derive the share type as shown.

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: