More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  Richard Siddaway's BlogPhotosProfileFriendsBlog Tools Explore the Spaces community

Blog

July 05

Passwords: The last word?

Comments from Martin and Stephen on this post - http://richardsiddaway.spaces.live.com/blog/cns!43CFA46A74CF3E96!1509.entry  - have produced a solution that does what I want. 

I can use Read-Host to get a secure string - so I don't have to type the password in clear or store it in the script or anywhere else. I can then convert that into a form I can use to create an AD account where the account is enabled and the password is usable.

$secpass = Read-Host "Password" -AsSecureString
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "userid", $secpass

New-QADUser -FirstName "Jo" -LastName "Smith" -DisplayName "Jo Smith" -SamAccountName "josmith" `
            -UserPrincipalName "josmith@manticore.org" -Name "Jo Smith" `
            -ParentContainer "ou=staff,dc=manticore,dc=org" -City "London" `
            -UserPassword $cred.GetNetworkCredential().Password

Set-QADUser -Identity "manticore\josmith" -ObjectAttributes @{useraccountcontrol=512}

As before we get the password as a secure string.  We then use System.Management.Automation.PSCredential  to generate a security credential.  It is a dummy credential that we won't be using anywhere so the userid can be anything and for the password we use our secure string.

We then create the user account as before except we use $cred.GetNetworkCredential().Password to get the password in a form that is usable by AD.

More info on System.Management.Automation.PSCredential  can be found here

http://msdn.microsoft.com/en-us/library/system.management.automation.pscredential(VS.85).aspx

Thank you to every one who has commented on this series of posts.  If the answer is out there the PowerShell community will find it.

 

Share this post :

 

Technorati Tags: ,

July 04

By The Way

With reference to my last post - I finally read down to the bottom of the post I quoted and saw the comment about put " " round the password when trying to set it.  It allows the creation of the account and account enabling but the password is not usable to logon.

I have a password history of 24 set on the domain but it still let me change the users password in AD Users & Computers to the value that I had tried to set as a secure string meaning that whatever the password was set to it wasn't what I thought it was.

Still looks like you can't use secure strings as passwords.  Unless someone knows better.  If so please let me know as I am intrigued by this.

 

Share this post :

 

Technorati Tags: ,

 

Passwords when creating AD Users

In this post http://richardsiddaway.spaces.live.com/blog/cns!43CFA46A74CF3E96!1504.entry I showed how to create a user account in AD as part of a series in developing functionality in a script.

In a comment Bruno pointed out I had an error in the script in that I was using

$defaultPassword = Read-Host "Please enter default Password" -asSecureString

to get a password and then using

$newuser.SetPassword($defaultPassword.ToString())

to set the password.

If a user tries to logon with that password the logon attempt will fail.

If you don't use the .ToString() method when setting the password the operation will fail, a password will not be set and the account will not be enabled.

The password must be entered as an ordinary string if using Read-Host or embedded in the script or passed as an argument.  Unless you use the code Bruno obtained http://blog.netnerds.net/2007/07/powershell-exception-has-been-thrown-by-the-target-of-an-invocation/ you will not be able to use a secure string in your script and have the user logon

This started me wondering about the AD cmdlets and how they behaved so I tried a similar script

$password = Read-Host "Password" -AsSecureString

New-QADUser -FirstName "Jo" -LastName "Smith" -DisplayName "Jo Smith" -SamAccountName "josmith" `
            -UserPrincipalName "josmith@manticore.org" -Name "Jo Smith" `
            -ParentContainer "ou=staff,dc=manticore,dc=org" -City "London" -UserPassword $password

Set-QADUser -Identity "manticore\josmith" -ObjectAttributes @{useraccountcontrol=512}

and ran through a similar exercise:

- get password as secure string => password setting fails

- get password as secure string  and convert to string => user created but can't logon

- get password as string => account created and user can logon

To summarise - we can't use a secure string as the password when creating AD accounts.  This is a pity as we now have to either type the password on screen during the creation process or embed it in the script.

My immediate recommendation would be to use Read-Host but then use CLS to immediately clear the screen and remove the password from view.  Alternatively embed the password in the script but don't enable the script.  You could then reset the password and enable the account as a second phase.  My preference is for the first method.

I am using PowerShell V2 CTP2 and the latest version of the cmdlets so I don't think it is a version issue.

The other annoyance is that using secure string made for a good demo - time to change that as well.

On the other hand this does show the strength of the PowerShell community in catching this error.

Thanks to Bruno

 

Share this post :

 

Technorati Tags: ,

 

IIS provider

Installed the IIS provider.  One quick thing to note is that if you don't start PowerShell with elevated permissions you will see the following message

Process should have elevated status to access IIS configuration data.

 

Share this post :

 

Technorati Tags: ,

July 03

IIS 7 PowerShell provider CTP 2

CTP 2 of the IIS 7 PowerShell provider is available.  There is a large increase in the number of cmdlets available:

Backup-WebConfiguration                                                                           
Clear-FrebData                                                                                    
ConvertTo-WebApplication                                                                          
Disable-Freb                                                                                      
Disable-WebModule                                                                                 
Enable-Freb                                                                                       
Enable-WebModule                                                                                  
Get-AppDomain                                                                                     
Get-AppPoolState                                                                                  
Get-ConfigurationBackup                                                                           
Get-WebHandler                                                                                    
Get-WebModule                                                                                     
Get-WebRequest                                                                                    
Get-WebSiteState                                                                                  
New-AppPool                                                                                       
New-FtpSite                                                                                       
New-ManagedWebModule                                                                              
New-VirtualDirectory                                                                              
New-WebApplication                                                                                
New-WebBinding                                                                                    
New-WebHandler                                                                                    
New-WebModule                                                                                     
New-WebSite                                                                                       
Remove-AppPool                                                                                    
Remove-ConfigurationBackup                                                                        
Remove-VirtualDirectory                                                                           
Remove-WebApplication                                                                             
Remove-WebBinding                                                                                 
Remove-WebHandler                                                                                 
Remove-WebModule                                                                                  
Remove-WebSite                                                                                    
Restart-AppPool                                                                                   
Set-WebBinding                                                                                    
Set-WebHandler                                                                                    
Set-WebModule                                                                                     
Start-AppPool                                                                                     
Start-WebSite                                                                                     
Stop-AppPool                                                                                      
Stop-WebSite
                 

The provider can be downloaded from iis.net.

More details here http://blogs.msdn.com/powershell/default.aspx

I will be looking at this very soon.  The additional cmdlets look very good.

 

Share this post :

 

Technorati Tags: ,

                                                                      

July 02

AD User Creation Pt2

Time to actually create the user.  One of the things with PowerShell and Active Directory is that there are a number of ways of achieving a particular task.  This is one way of doing it.

## new-user.ps1
##  read a CSV file and create users
##
$ADs_UF_NORMAL_ACCOUNT = 512   ## enables account and sets password required

## get default passsword - encrypted so not stored in script
$defaultPassword = Read-Host "Please enter default Password" -asSecureString
## get the domain
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = $dom.GetDirectoryEntry()
$search = [System.DirectoryServices.DirectorySearcher]$root

## read csv file
$users = Import-Csv users.csv
foreach ($user in $users){
## test if userid exists
$id = $user.userid
$search.Filter = "(samAccountName=$id)"
$result = $search.FindOne()

    if ($result -ne $null)    {
        Write-Host $user.userid, " Exists"
    }
    else {
        ## create user name
        $strusr = $user.FirstName + " " + $user.LastName
        $ldapstr = "LDAP://OU=Staff," + $root.distinguishedname
        $target = ([ADSI] $ldapstr).psbase
        $userlist = $target.Get_Children()
        $newuser = $userlist.Add("cn=" + $strusr, "user")
        $newuser.SetInfo()
        $newuser.samaccountname = $user.userid
        $newuser.givenName =  $user.FirstName
        $newuser.sn = $user.LastName
        $newuser.displayName = $strusr
        $newuser.userPrincipalName = $user.userid + "@" + $dom.Name
        $newuser.SetInfo()
        $newuser.SetPassword($defaultPassword.ToString())
    ## normal user that requires password & is enabled
        $newuser.userAccountControl = $ADs_UF_NORMAL_ACCOUNT
        $newuser.SetInfo()
    # set User must change password at next logon flag
        $newuser.pwdLastSet = 0
        $newuser.SetInfo()
    ## now set the location
        $newuser.l = $user.Location
        $newuser.SetInfo()
        Write-Host "Created Account for: "  $newuser.Displayname
    }

}

The password is set as a secure string using Read-Host

Take the script we had last time and replace the script block after the else statement as shown.

Get a directory entry for the OU where we want to create the user using [ADSI].  Add the user as child of the OU.

Work through the parameters setting the data from the CSV.  Note the use of setInfo() to commit the changes. 

 

Share this post :

 

Technorati Tags:

PowerShell Virtual Lab

A recent addition to the TechNet virtual labs is 10 Cool PowerShell Scripts.  In the words of the access page "After completing this lab, you will be better able to quickly create administration scripts with Windows Server 2008."  The lab is available from http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032380227&EventCategory=3&culture=en-US&CountryCode=US

 

Share this post :

 

Technorati Tags:

July 01

AD User Creation

I had a message left on my blog asking if I had a script for user creation in AD.  The requirements are

Inputs:

First Name
Last Name
Location (London, Hastings, Woking etc)
UserID

Main

Loop
Check if UserID already in use - if so display message including existing user details
End Loop when UserID unique

If Location London then
Get free space on FS1 & FS2 user LUNS
Store london server to use
End

Create new user in Staff OU
Set profile attribute
Add as member to _site_home group
Set password to random password (that meets complexity requirements)
Set password to change at next logon
Create Home directory

Get number of users on all Exchange DB's
Create mailbox on smallest DB
Set calendar default to reviewer

I don't actually have a single script to do all of this.  Over a few posts I will show how create this type of script.  I will show how to do this with a script and then using the AD cmdlets.

We start with a csv file that contains the input data

FirstName,LastName,Location,userid
Richard,Jones,London,Richard
Jo,Smith,Hastings,josmith
Fred,Robinson,Woking,frobinson

We input that file into a script

## new-user.ps1
##  read a CSV file and create users
##
## get the domain
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = $dom.GetDirectoryEntry()
$search = [System.DirectoryServices.DirectorySearcher]$root

## read csv file
$users = Import-Csv users.csv
foreach ($user in $users){
## test if userid exists
$id = $user.userid
$search.Filter = "(samAccountName=$id)"
$result = $search.FindOne()

if ($result -ne $null)
{
  Write-Host $user.userid, " Exists"
}
else {Write-Host $user.userid " Does not exist"}

}

Start by using System.DirectoryServices.ActiveDirectory to get the current domain and create a DirectorySearcher.

Read the csv file and put the contents into a foreach loop.  Test the userid against the samAccountNames in the domain.  If a match is found then list the fact.

Next time we will create the user account

 

Share this post :