Wednesday, December 19, 2012

Thursday, December 6, 2012

Id10T Errors and P.E.B.K.A.C Patience


I work in a fairly large organization and sometimes the things I see amaze me. For instance yesterday I spent 20 minutes on the phone with a user. Granted I have spent longer trying to fix an issue, but this was a simple password reset. Why for the life of me after 5 minutes I didn't just chalk one up for P.E.B.K.A.C but I genuinely thought there was a problem. So it started off with the user calling into our help line. The user stated that they cannot login to their workstation; this happens fairly frequently as some users I would rather take a hammer to a puppy then give them a computer. so I reset the users password using a little PowerShell function I created recently:

Function Reset-Pass ($samname) {
Set-ADAccountPassword -Identity $samname -reset -NewPassword (ConvertTo-SecureString -AsPlainText "Id10T" -Force)
Set-ADUser -Identity $samname -Enabled $TRUE -ChangePasswordAtLogon $true
Unlock-ADAccount -Identity $samname
“Password Reset for $samname”
}

I explained to the user that I had reset his password and they would need to use the new password which I provided him with. In the background on the phone I hear the user slowly, ever so slowly chicken pecking in his new password. {Tack}…{Tack}…{Tack}……………..{Tack}…{Tack}………..{Tack}… you get the point I’m sure.  After about 3 minutes of this noise their done. The user then responds with “ it didn't work, still won’t let me in. so once more I reset his password. Another 3 minutes pass by as I listen to the ever so soothing sound of him breathing into the handset of his phone. Same outcome, the user is not able to get into his computer. Finally I get frustrated enough I use system centers remove control viewer. Get that all up and running punch in the user’s computer name with the force of The Almighty Thor striking a frost giant with his hammer. The screen flickers and now I see what the user is seeing. Without desk flipping, ripping off my id badge and walking out.


I calmly explain to the user in my best “I’m not about to murder you and your fifteen cats” voice that all they must do is hit okay and change their password. I really wanted to ask them for fifteen minutes of my life back, but these are the pitfalls of IT. Today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.

Tuesday, December 4, 2012

Why Error Checking Is The Bird, And The Bird Is The Word!



Today started as a normal day. I came into the office did my normal morning routine. Checked the many different mailboxes I’m tasked with up keeping, made sure all of our websites were up and running. Then i received an email from one of my supervisors. He was letting me know that he noticed something a little off. See recently i created a script that automatically uploads a user’s photo to their Active Directory account. Basically it puts Jim Bob’s stupid face on Jim Bob’s stupid account that he doesn’t even know how to log into. So doing some research into the errors I’m receiving ex:

Set-ADUser : A value for the attribute was not in the acceptable range of values
At C:\Scripts\PhotoUpdate\Photos.ps1:43 char:11
+ Set-ADUser <<<<  $horse.SamAccountName -Replace @{thumbnailPhoto=$photo}
    + CategoryInfo          : NotSpecified: (JoseMo:ADUser) [Set-ADUser], ADException
    + FullyQualifiedErrorId : A value for the attribute was not in the acceptable range o
   f values,Microsoft.ActiveDirectory.Management.Commands.SetADUser


I find that the photos even after resizing are upwards of 1MB. Now you might be thinking “1 MB is really small. Dude!”  WRONG! There is a 100KB Cap on what information you place in the field itself. So looking back over all of the staff pictures that were nestled softly in the directory bedding I realize there is no telling how many of these pictures never uploaded. Looking into it more than 1000 didn’t. So now I’m spending the rest of today with my old “frenemy” PhotoShop. So for today’s PowerShell tip: Implement Error Checking Dammit! You never know when your shit will break. So here it is the script that saved the day. 






#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
################################################ Import AD snap-in ####################################################
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
Import-Module ActiveDirectory


# Make a Directory where the modified pictures will go
mkdir \\file\staffidphotos$\AD

# Remove the old error file
rm C:\Scripts\PhotoUpdate\Nope.txt

# This script requires ImageMagick http://www.imagemagick.org
$tool = "C:\ImageMagick\convert.exe"

# Create New Erro File
New-Item C:\Scripts\PhotoUpdate\Nope.txt -type file

# Set the Resize Command
$cmd = "resize 9126@"
# Still setting
$test = "-"

# Get today's date
$Date=get-date
# Go Back 29 days
$Date1=$Date.AddDays(-29)


# This command will get all of the pictures that has been uploaded to your picture directory that are newer than 29 days ago
get-childitem "\\file\staffidphotos$" | where-object {$_.mode -notmatch "d"} | where-object {$_.lastwritetime -gt $date1} | foreach {$_.name} | Out-File "C:\Scripts\PhotoUpdate\NewPictures.txt"

# Simply Removes Empty Lines
(Get-Content "C:\Scripts\PhotoUpdate\NewPictures.txt") | where {$_ -ne ""} > "C:\Scripts\PhotoUpdate\NewPictures.txt"

# Get me them beautiful accountnames
$dog = Get-Content "C:\Scripts\PhotoUpdate\NewPictures.txt"

foreach ($person in $dog){
# CHecks to make sure the user has an AD account
$gator = Get-ADUser -Identity $person
If  ($gator -like $null){
# Adds the users name to here if they do not have an account
Add-Content C:\Scripts\PhotoUpdate\Nope.txt "$person"

}
else
{
echo $gator.SamAccountName
$file = "\\file\staffidphotos$\$person"
$file1 = "\\file\staffidphotos$\AD\$person"
Echo $file

# Runs the command to resize the picture
invoke-expression "$tool $file $test$cmd $file1"

# Formats the New photo to bytes
$photo = [byte[]](Get-Content $file1 -Encoding byte)

# Sets the Picture to the users account
Set-ADUser $gator.SamAccountName -Replace @{thumbnailPhoto=$photo}
}}


# Removes the old photos
rm \\file\staffidphotos$\AD -Recurse -Force
rm C:\Scripts\PhotoUpdate\NewPictures.txt


#Sends an email with who was not updated
$i = 0
$datey = Get-Date -Format %M/%d/%y
$FromAddress = "it@test.com"
$ToAddress = "it@test.com"
$paste = Get-Content C:\Scripts\PhotoUpdate\Nope.txt
$check = 1..$paste.count
while ($i -le $paste.count-1) { 
$check[$i] = $paste[$i] + "<br>" 

$i++ 
} 
$check12 = $check  -replace ".jpg",""
$MessageSubject = "Picture not updated for these users"
$MessageBody = "No Account on $datey for User:<br>$check12"
$SendingServer = "exchane.test.com"
send-mailmessage -from $FromAddress -to $ToAddress -subject $MessageSubject -body $MessageBody -smtpServer $SendingServer -BodyAsHtml

Monday, December 3, 2012

I've Got A First Class Case of Copy User



I have worked with user accounts for a long time now and while working with the default Active Directory GUI is very easy, I wanted more "POWER!" and I’m talking PowerShell. 


I first wrote this little script as a basic user copy at first. Three or four lines of code were all i was really comfortable to do. This really got my PowerShell juices flowing and i wanted more.



$Copied = Get-ADUser -Identity $user -Properties *
$parent = $Copied.DistinguishedName -replace $copied.Name -replace "cn=,",""

New-ADUser -SamAccountName $person.SamAccountName -GivenName $person.GivenName -Surname $person.Surname -DisplayName $person.Name -Name $person.Name -UserPrincipalName "$($person.SamAccountName)$UserPrincipalmail" -Company $Copied.Company -Department $Copied.Department -Manager $Copied.Manager -title $Copied.Title -Description $Copied.Description -Office $Copied.Office -scriptpath informationFITS.cmd




Then i got into reading more into PowerShell and saw how much power it really has behind it.  So i added the mailbox permissions copy and group memberships. The first tricky part was getting just the names of the groups back from the command. After i figured that out it kind of just fell into place for me. I was hooked on what could be done with PowerShell.



$groups = (GET-ADUSER –Identity $user –Properties MemberOf).MemberOfforeach ($group in $groups) { Add-ADGroupMember -Identity $group -Members $person.SamAccountName}$count = $groups.count
Enable-Mailbox -Identity $person.SamAccountName  -Database "Your Mail Database"Start-Sleep -s 10Set-Mailbox -Identity $person.SamAccountName  -IssueWarningQuota 104857600 -ProhibitSendQuota 157286400 -ProhibitSendReceiveQuota 209715200 -UseDatabaseQuotaDefaults $false




So here it is folks the final result of my first ever PowerShell script. 






################################################ Import AD snap-in ####################################################

Import-Module ActiveDirectory


######################################## Import the Exchange 2010 snap-in #############################################

if ( (Get-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue) -eq $null) {
 Write-Verbose "Exchange 2010 snapin is not loaded. Loading it now."
 try { Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010; Write-Verbose "Loaded Exchange 2010 snapin" }
 catch { Write-Error "Could not load Exchange 2010 snapins!"; }
}


############################################## Countdown timer fuction ################################################





#put user to copy Username Here
$user = "Copied Username here"

# Imports user info from CSV file
$info = Import-Csv "Your CSV location here"

# Place your AD Ending for its Principal
$UserPrincipalmail = "@yourcompany.com"


foreach ($person in $info){
# Sets the users name for Output
$bigname = $person.Name

# Gets all of the users info to be copied to the new account
$Copied = Get-ADUser -Identity $user -Properties *
$parent = $Copied.DistinguishedName -replace $copied.Name -replace "cn=,",""
# Creates the user from the copied properties
New-ADUser -SamAccountName $person.SamAccountName -GivenName $person.GivenName -Surname $person.Surname -DisplayName $person.Name -Name $person.Name -UserPrincipalName "$($person.SamAccountName)$UserPrincipalmail" -Company $Copied.Company -Department $Copied.Department -Manager $Copied.Manager -title $Copied.Title -Description $Copied.Description -Office $Copied.Office -scriptpath informationFITS.cmd

# lets you know the account was created successfully
"$bigName Created Successfully"

# Moves the user from the default Users OU to its
dsmove "CN=$($person.name),OU=Sales,DC=Yourcompany,DC=Com" -newparent $parent

# Sets the Default password that the user will login with then change
Set-ADAccountPassword -Identity $person.SamAccountName -reset -NewPassword (ConvertTo-SecureString -AsPlainText "ABCD@1234" -Force)

# lets you know the password has been set
"$bigName Passowrd Set"

Start-Sleep -s 10

# Sets it so the new user will have to change the password upon logging in
Set-ADUser -Identity $person.SamAccountName -Enabled $TRUE -ChangePasswordAtLogon $true


# gets groups from the Copied user and populates the new user in them
$groups = (GET-ADUSER –Identity $user –Properties MemberOf).MemberOf
foreach ($group in $groups) { 

Add-ADGroupMember -Identity $group -Members $person.SamAccountName
}
$count = $groups.count
"$bigName Added to $count Groups"


# Creates the New users mailbox with the mailbox quotas 100MB,150MB,200MB
Enable-Mailbox -Identity $person.SamAccountName  -Database "Your Mail Database"
Start-Sleep -s 10
Set-Mailbox -Identity $person.SamAccountName  -IssueWarningQuota 104857600 -ProhibitSendQuota 157286400 -ProhibitSendReceiveQuota 209715200 -UseDatabaseQuotaDefaults $false

"$bigName Mailbox Created"

# Gets the full access mailbox permissions of the copied user and applies them to the new user
$mailboxPerm = get-mailbox -ResultSize Unlimited | get-mailboxpermission -User $user
$mailboxes = 1..$mailboxPerm.count
$i = 0 

while ($i -le $mailboxPerm.count-1) { 
$mailboxes[$i] = $mailboxPerm[$i].Identity.Name

$i++ 
}
foreach ($Mailbox in $mailboxes) {
Add-MailboxPermission $mailbox -User $person.SamAccountName -AccessRights FullAccess
Set-Mailbox -GrantSendOnBehalfTo $person.SamAccountName -Identity $mailbox
}


# Copies the copied users script

pushd \\your\script\directory

copy "$($user).cmd" "$($person.SamAccountName).cmd" 

popd
"$bigName Script Created"
}