Sunday 8 February 2015

How to edit file system permissions in Powershell

http://blogs.technet.com/b/heyscriptingguy/archive/2014/11/22/weekend-scripter-use-powershell-to-get-add-and-remove-ntfs-permissions.aspx

ScriptingGuy in this blog has dealt with and ably addressed the various limitations of the original system of setting permissions in Windows using Powershell, which was that you had to manipulate ACLs, never particularly easy, and also had the horrible 260 character path abortion of Windows 32 API to contend with. By providing the NTFSSecurity module, permissions have become much easier to configure in Powershell. All this is great because I have some permissions work to do in some of my scripts. Even on my home computer I would like to set permissions with a script command rather than muck around with Windows Explorer (waiting for it to update all the permissions on a big folder is quite time consuming).

Thursday 5 February 2015

Powershell Community Extensions and Carbon

What makes Powershell so useful is not only the excellent built-in capabilities, but the various extension modules developed for it by third parties. Last time I talked about some Google Apps extensions, which I am currently testing and look very promising. Today I am going to take a quick look at Powershell Community Extensions and Carbon.

Powershell Community Extensions, according to the ScriptingGuy blog, fills in some gaps in the general purpose cmdlets in Powershell, because Powershell is a relatively new scripting environment. To wit: 
"PowerShell Community Extensions is a PowerShell module that provides a number of widely useful cmdlets.  PSCX is not affiliated with Microsoft or the Windows PowerShell team at Microsoft.  We are a few (at the moment) passionate PowerShell users who wanted more cmdlets than Microsoft was able to deliver in v1 and v2.  So we have taken it upon ourselves to create some of those cmdlets and make them available to the community."
 There are quite a number of cmdlets added by the current release of PSCX (v3.2) which encompass quite a number of useful functions. Some of the ones that I found interesting include 7-zip archive management, file junction management, email send, terminal services sessions management and VHD mounting.

Here is the description of Carbon from their website:
Carbon is a DevOps PowerShell module for automating the configuration of Windows 2008, Windows 2008 R2, 7, 2012, and 2012 R2 computers. Carbon can configure and manage:
  • Local users and groups
  • IIS websites, virtual directories, and applications
  • Certificates
  • .NET connection strings and app settings
  • Junctions
  • File system permissions
  • Hosts file
  • INI files
  • Performance counters
  • Services
  • Shares
  • Windows features/components
And much more!
 Again you will notice junctions are featured - and that one of my current scripting project uses junctions. I got to hear about these two projects because of the junction extensions. It will be interesting to see how useful these extensions are as I develop and test my script.

Tuesday 3 February 2015

Managing Google Apps with Powershell

You don't have to be too knowledgeable about computing to know Microsoft and Google are at each other's throats constantly in the IT world. Fortunately, that doesn't extend to every level, and so it is with some pleasure I have started to investigate the ability to use Powershell to provision and manage Google Apps for Education.

When I first started managing Google Apps domains for schools I went out looking for a useful management tool to do bulk account management (since Google doesn't provide for this in their admin console) and after a time discovered the Dito GAM tool (Google Apps Manager). Since then I have used it to perform some aspects of account management, which included bulk account suspension when the accounts we had created for students weren't immediately required. Whilst this tool has proved very versatile it lacks capability to be useful when called in scripts and also can't manage the Google Apps shared contacts (we need something to manage this because it is another capability lacking in the Google Apps console).

So at this point I am starting to look at Powershell extensions to manage Google Apps instead. Assuming they conform to Powershell conventions and interoperability they will be usable in Powershell scripts that I write and can therefore be easily integrated into the student add script I am working on. So far here are some tools I have found and will be evaluating:
Of these, GShell looks the most promising. GDataCmdLet is currently the only one of the three that supports contact management, but hasn't been updated since 2010.

Using Powershell with Active Directory [3]

So continuing on my Powershell with AD series, here is my student account script newly written in Powershell which is calling Get-ADUser to look up accounts in Active Directory.

function AddStudent($StudentData)
{
    write-host "Add " + $StudentData.LName + " " + $StudentData.FName
}

function UpdateStudent($StudentData)
{
    write-host "Update " + $StudentData.LName + " " + $StudentData.FName
}

function RemoveStudent($StudentData)
{
    write-host "Remove " + $StudentData.samAccountName
}

function CreateSubjects($StudentData)
{
}
For now, my function calls are just stubs that tell me they were called and what function they perform. The code for the dirty work still has to be written.

#First check CSV input against AD
#EnrolNum,Lname,Fname,Class,Pwd,StudentID,Logon
$Students = Import-CSV -Path "C:\Users\Patrick\NewStudents.txt"
foreach ($Student in $Students)
{
    # Look up the student in Active Directory to see if they are a current member
        $StudentID = $Student.StudentID
        $CurrentStudent = Get-ADUser -Filter 'EmployeeID -eq $StudentID'
        if ($CurrentStudent -ne $null)
        {
            UpdateStudent($Student)   
        }
        else
        {
            AddStudent($Student)
        }
}

This part of the script is getting the student accounts in from a CSV file. The column names are in the first line of the file and have to be exactly as shown. Then when I reference a row, I can use the same column name that was specified in the CSV file. We used the EmployeeID field in Active Directory to store the StudentID which in this case is the primary key from the database of the Student Management System. Even if the student's name changes, this number never changes. We assume there is only one result from the search, as there should be, and if the result is null (nothing found) we call our AddStudent function to add the account; otherwise we call UpdateStudent to update any changes to the student's data, such as their username.

#Next check AD against CSV
$ADStudents = Get-ADUser -Filter * -SearchBase "ou=HCS-Students,dc=hcs,dc=local" -SearchScope Subtree -Properties employeeID
foreach ($ADStudent in $ADStudents)
{
    $found = $false
    foreach ($Student in $Students)
    {
        if ($Student.StudentID -eq $ADStudent.EmployeeID)
        {
            $found = $true
            break
        }
    }
    if ($found -eq $false)
    {
        RemoveStudent($ADStudent)
    }
}


The main function of this block of code is to do a reverse lookup from the existing accounts in Active Directory to see if these accounts are found in the CSV file. If not, then RemoveStudent is called to disable their account and archive their home drive. Note that in this case we have set the filter to * (all accounts) and instead have used SearchBase and SearchScope to specify where to find the accounts in AD. We also have to use the Properties parameter to get EmployeeID back from AD because it isn't in the set of default properties returned.


In theory Where-Object should make it possible to do the reverse lookup but I wasn't able to make this work so I have the double Foreach loops with the breakout capability in the inner loop. It's still fast enough.

#Now create the subject links for the students
$AllStudents = Get-ADUser -Filter 'enabled -eq $true' -SearchBase "ou=HCS-Students,dc=hcs,dc=local" -SearchScope Subtree
foreach ($Student in $AllStudents)
{
    CreateSubjects($Student)
}
The last piece of code is to do with setting up subject folders in the student's home drive and then creating junctions to them for the teacher to find those folders when they are marking work. This time in addition to SearchBase and SearchScope we have used a filter to find accounts that are enabled. The code needs to be improved so that it also updates subjects such as when a new subject is added. Command line parameters are also needed to allow it to handle only a partial input file such as would be received to add only one or two accounts at a time, instead of the full start of year file.

Well that is enough for now and next time I will post the extra code for the full working version of the script.