Monday 24 May 2010

Disable/Enable Outlook Web Access (OWA) using powershell Exchange 2003 - protocolSettings

This took several hours of googling binging so hopefully this will save people some time, and me when i forget in a few days!

What we'll do:
Query AD and find accounts that have OWA disabled and then re-enable them.

When accessing AD with powershell you REALLY need to use the FREE -as in beer addons from Quest: http://www.quest.com/powershell/activeroles-server.aspx install that then crack open powershell, for this i'm using powershell 2...

For the purposes of this everything in courier is powershell script

first add the snapin you just installed:


Add-PSSnapin Quest.ActiveRoles.ADManagement

try it:

Get-QADUser thenameofyouraccount | Select-Object name

That should bring back your name, if it doesn't it can't connect to AD, i'm guessing you can fix that yourseld :)

Now, to build the LDAP string to get back the users we're looking for:


$strFilter = "(&(&(objectcategory=Person)(protocolSettings=HTTP§0§1§§§§§§)(!(userAccountControl:1.2.840.113556.1.4.803:=2))))"

the above brings back all person objects whose account is enabled and their protocolSettings is set to disable WebAccess.

FYI:
HTTP§0§1§§§§§§ = Disabled
HTTP§1§1§§§§§§ = Enabled

This is the same for all Protocol settings the first switch is the enabler.

Now we need to connect to AD, i haven't done this using the Quest addin and i'm not sure why, its useful to know though:

 
$objDomain = New-Object System.DirectoryServices.DirectoryEntry


$objSearcher = New-Object System.DirectoryServices.DirectorySearcher


$objSearcher.SearchRoot = $objDomain


$objSearcher.PageSize = 1000


$objSearcher.Filter = $strFilter


$objSearcher.SearchScope = "Subtree"

That should all be pretty straight forward, the PageSize appears to be a bug, when its not set or set to another number it only returns 1000 records, at 1000 its returns all, go figure! this is exactly the opposite behaviour as in .net proper.
 
You need a few properties to bring back so we'll tell powershell to preload them as part of the AD search call:

 
$colProplist ="distinguishedName", "name", "sAMAccountName", "Description"


foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

Bring the results back!
to get how many you've got back:
$colResults = $objSearcher.FindAll()

Now go through each record and change the protocolSettings using the QuestAddin, this can be done in theory from AD but i could never get it to play nicely with the string array.
Write-host "Total objects: $($colResults.count)"

 
foreach ($objResult in $colResults)



{


$objItem = $objResult.properties;


Set-QADUser -identity "$($objItem.distinguishedname)" -ObjectAttributes @{protocolSettings='IMAP4§1§1§4§ISO-8859-1§0§1§0§0','POP3§1§1§4§ISO-8859-1§0§§§','HTTP§1§1§§§§§§'}


}
I'm actually enabling all the protocol settings just change the 1 after the first § to 0 to disable them.

Make sure you're using the right encoding!
 
 
To check you've changed something:


Get-QADUser  -IncludedProperties('protocolSettings')

Select-object protocolSettings, name

That's it, bear in mind it might take a few (2hrs 15mins max -depending on your TTL in exchange) for the properties to be picked up, also if you've got any connections currenty open you may encounter strange behaviour until the connections are re-authenticated.

the complete script:
Add-PSSnapin Quest.ActiveRoles.ADManagement



$strFilter = "(&(&(objectcategory=Person)(protocolSettings=HTTP§0§1§§§§§§)(!(userAccountControl:1.2.840.113556.1.4.803:=2))))"



$objDomain = New-Object System.DirectoryServices.DirectoryEntry


$objSearcher = New-Object System.DirectoryServices.DirectorySearcher


$objSearcher.SearchRoot = $objDomain


$objSearcher.PageSize = 1000


$objSearcher.Filter = $strFilter


$objSearcher.SearchScope = "Subtree"






$colProplist ="distinguishedName", "name", "sAMAccountName", "Description"


foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}



$colResults = $objSearcher.FindAll()


Write-host "Total objects: $($colResults.count)"


foreach ($objResult in $colResults)


{


$objItem = $objResult.properties;


Set-QADUser -identity "$($objItem.distinguishedname)" -ObjectAttributes @{protocolSettings='IMAP4§1§1§4§ISO-8859-1§0§1§0§0','POP3§1§1§4§ISO-8859-1§0§§§','HTTP§1§1§§§§§§'}


}

Wednesday 12 May 2010

MVC 2 Editor templates and complex viewmodels

Have a complex view model with nested models and can't get the real PropertyName from

ViewData.ModelMetadata.PropertyName

use

ViewData.TemplateInfo.HtmlFieldPrefix
ahh but this returns parentmodel.propertyName
so
ViewData.TemplateInfo.HtmlFieldPrefix.Replace(".","_")
done.
jquery date picker example:

$(document).ready(function() {
 $('#').datepicker({ yearRange: '-120:+5', dateFormat: 'dd/mm/yy', changeMonth: true, changeYear: true });
});

Saturday 20 March 2010

Change the password of a local computer user remotely using .net

Ever wanted to change the password of the local administrator account (or any local user account for that matter) in .net? Here's how: Code is in white on blue!

Make sure you import
System.DirectoryServices

Imports System.DirectoryServices

First things first we need to check to see if the computer is turned on, lets try a quick ping


Dim pinger As New Net.NetworkInformation.Ping
Try
Dim result = pinger.Send(MachineName)
If result.Status <> Net.NetworkInformation.IPStatus.Success Then
'unable to connect
Return False
End If
  Catch ex As Exception
'unable to connect
Return False
End Try

Nothing complicated about that and you could enhance it to provide some feedback

Now to connect to the machine for this use
DirectoryEntry, its got quite a few parameters/overloads but for this we're only interested in:

  • Address of the computer we're trying to connect to
  • Username of the account we're going to be using to change the password -must have the ability to change a local user password so if you use a AD account make sure its part of the admin group on the target machine 
  • Password of the above account
  •  Authentication -the machine won't let you change the password if its not a secure connection!

All together looks like:
Dim de As New DirectoryEntry(String.Format("WinNT://{0}", MachineName), "mydomain\accountname", " accountpassword", AuthenticationTypes.Secure)


quick check to see if  its worked

If de Is Nothing Then
  'couldn't connect
Return False
End If

Now, technically you should be able to give it the path WinNT://machinename/Nameoftheaccount but i couldn't get this to work, just throws 80005000 errors so....

Query the directory entry to find the account we're looking for, in this case: Administrator
Dim admin = de.Children.Find("Administrator")
 
If admin Is Nothing Then
'couldn't connect or find account
Return False
End If


Finally to change the password: Bear in mind that the password must conform to any complexity requirements you have setup!

Try
  admin.Invoke("SetPassword", "New password")
admin.CommitChanges()
'Done! 
Catch ex As Exception
Return False
End Try


The code in full as a function:

Public Function ChangeLocalUserPassword(ByVal MachineName As String, ByVal LocalUser As String, ByVal Pass As String) As Boolean
Dim pinger As New Net.NetworkInformation.Ping
Try
Dim result = pinger.Send(MachineName)
If result.Status <> Net.NetworkInformation.IPStatus.Success Then
'unable to connect
Return False
End If
Catch ex As Exception
Return False
End Try




Dim de As New DirectoryEntry(String.Format("WinNT://{0}", MachineName), "mydomain\accountname", " accountpassword", AuthenticationTypes.Secure)
 
If de Is Nothing Then
'couldn't connect or find account
Return False
End If
Dim admin = de.Children.Find(LocalUser)
 
If admin Is Nothing Then
'couldn't connect or find account
Return False
End If


Try
admin.Invoke("SetPassword", Pass)
admin.CommitChanges()
'Done!
Catch ex As Exception
Return False
End Try
End Function

Thursday 18 March 2010

Mix 10: Useful/Interesting videos

Web form & mobile design, common sense? maybe but its nice to see how crazy we can be:
http://live.visitmix.com/MIX10/Sessions/EX03

asp.net MVC2 new shiny toy to play with, Haack guide to new things:
http://live.visitmix.com/MIX10/Sessions/FT04

mvc security:
http://live.visitmix.com/MIX10/Sessions/FT05

first!