WSUS approve patches/update with specific criteria via powershell

There is a lot happening in this script so I will try to cover as much as possible. This scripts goes through and approves and decline updates/patches that meet a specific criteria, if it does not meet the criteria it will leave the updates/patches in an unapproved state. The reason I need to come up with this scripts was because the amount of time that it was taking me each month to got through each patch and see if it was applicable to our environment was taking far too long. We do not have any Itanium based servers, we only have 32 bit of windows server 2003, and 64 bit of windows server 2008. This script will let you first run a report of the list of patches that will be approved and declined. After your verify that your list is applicable to your criteria you can then run the approve option. This will approve and decline patches for computers in the “All Computers” group. If you need to get more granular than that I suggest you take a look at the $group variable and be sure that you get the specific computer group that you need.

$caption = "Choose Option";
$message = "What would you like to do with new updates?";
$report = new-Object System.Management.Automation.Host.ChoiceDescription "&Report Patches","Report";
$approve = new-Object System.Management.Automation.Host.ChoiceDescription "&Approve/Decline Patches","Approve";
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($approve,$report);
$answer = $host.ui.PromptForChoice($caption,$message,$choices,0)
#$answer 0=approve 1=report
##FINAL SCRIPT
$wsusserver = "YOUR IP ADDRESS OR SERVERNAME"
##Load required assemblies
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusserver,$False,8530)
##Retriving "All Computers" Group information
$group = $wsus.GetComputerTargetGroups() | where {$_.Name -eq 'All Computers'}
##Retriving list of unapproved updates
$updates = $wsus.GetUpdates()  | where {$_.IsApproved -eq $False -and $_.IsDeclined -eq $False}
########################################
#Itanium Updates
########################################
##Retrive a subset of updates where IA64 is in the legacyname
$IAUpdates = $updates | where {($_.LegacyName -like '*IA64*')}
Foreach ($IAUpdate in $IAUpdates) {
    switch ($answer){
        0 {$IAUpdate.Decline(); $msgDeclined = $msgDeclined + $IAUpdate.SecurityBulletins + "`t" + $IAUpdate.MsrcSeverity + "`t" + $IAUpdate.Title + "`n";break}
        1 {$msgDeclined = $msgDeclined + $IAUpdate.SecurityBulletins + "`t" + $IAUpdate.MsrcSeverity + "`t" + $IAUpdate.Title + "`n";break}
    }
    ##Uncomment the next line to check updates that are in an incorrect state
    #If ($IAUpdate.IsDeclined -ne "True") {$msgCheckTheseUpdates = $msgCheckTheseUpdates + $IAUpdate.Title + "`n"}
}
########################################
#Windows Security Updates Critical
########################################
##Revise list of unapproved updates
$updates = $wsus.GetUpdates()  | where {$_.IsApproved -eq $False -and $_.IsDeclined -eq $False}
##Retrive a subset of updates that are security updates and are of the windows family and have a MSRC serverity of Critical
$WSecCriticalUpdates = $updates | where {$_.UpdateClassificationTitle -eq 'Security Updates' -and $_.ProductFamilyTitles -like 'Windows' -and $_.MsrcSeverity -eq 'Critical'}
Foreach ($WSecCriticalUpdate in $WSecCriticalUpdates) {
    If ($WSecCriticalUpdate.LegacyName -like "*x64*" -and ($WSecCriticalUpdate.ProductTitles -like "*2008*") -or ($WSecCriticalUpdate.ProductTitles -like "*2012 R2*")) {
            switch ($answer) {
                0 {$WSecCriticalUpdate.Approve('Install',$group); $msgApproved = $msgApproved + $WSecCriticalUpdate.SecurityBulletins + "`t" + $WSecCriticalUpdate.MsrcSeverity + "`t" + $WSecCriticalUpdate.Title + "`n";break}
                1 {$msgApproved = $msgApproved + $WSecCriticalUpdate.SecurityBulletins + "`t" + $WSecCriticalUpdate.MsrcSeverity + "`t" + $WSecCriticalUpdate.Title + "`n";break}
            }
            ##Uncomment the next line to check updates that are in an incorrect state
            #If ($WSecCriticalUpdate.IsApproved -ne "True"){$msgCheckTheseUpdates = $msgCheckTheseUpdates + $WSecCriticalUpdate.Title + "`n"}
    }elseif ($WSecCriticalUpdate.LegacyName -like "*x86*" -and $WSecCriticalUpdate.ProductTitles -like "*2003*") {
            switch ($answer) {
                0 {$WSecCriticalUpdate.Approve('Install',$group); $msgApproved = $msgApproved + $WSecCriticalUpdate.SecurityBulletins + "`t" + $WSecCriticalUpdate.MsrcSeverity + "`t" + $WSecCriticalUpdate.Title + "`n";break}
                1 {$msgApproved = $msgApproved + $WSecCriticalUpdate.SecurityBulletins + "`t" + $WSecCriticalUpdate.MsrcSeverity + "`t" + $WSecCriticalUpdate.Title + "`n";break}
            }
            ##Uncomment the next line to check updates that are in an incorrect state
            #If ($WSecCriticalUpdate.IsApproved -ne "True"){$msgCheckTheseUpdates = $msgCheckTheseUpdates + $WSecCriticalUpdate.Title + "`n"}
    }else {
        switch ($answer) {
            0 {$WSecCriticalUpdate.Decline(); $msgDeclined + $WSecCriticalUpdate.SecurityBulletins + "`t" + $WSecCriticalUpdate.MsrcSeverity + "`t" + $WSecCriticalUpdate.Title + "`n";break}
            1 {$msgDeclined = $msgDeclined + $WSecCriticalUpdate.SecurityBulletins + "`t" + $WSecCriticalUpdate.MsrcSeverity + "`t" + $WSecCriticalUpdate.Title + "`n";break}
        }
        ##Uncomment the next line to check updates that are in an incorrect state
        #If ($WSecCriticalUpdate.IsDeclined -ne "True"){$msgCheckTheseUpdates = $msgCheckTheseUpdates + $WSecCriticalUpdate.Title + "`n"}
    }
}
########################################
#Windows Security Updates 1 month old
########################################
##Revise list of unapproved updates
$updates = $wsus.GetUpdates()  | where {$_.IsApproved -eq $False -and $_.IsDeclined -eq $False}
##Retrive a subset of updates that are security updates and are of the windows family and DO NOT have a MSRC serverity of Critical
$WSecNoneCriticalUpdates = $updates | where {$_.UpdateClassificationTitle -eq 'Security Updates' -and $_.ProductFamilyTitles -like 'Windows' -and $_.MsrcSeverity -ne 'Critical'}
Foreach ($WSecNoneCriticalUpdate in $WSecNoneCriticalUpdates) {
    If ($WSecNoneCriticalUpdate.LegacyName -like "*x64*" -and ($WSecNoneCriticalUpdate.ProductTitles -like "*2008*") -or ($WSecNoneCriticalUpdate.ProductTitles -like "*2012 R2*")) {
            ##Getting the createdate of each update and storing it in a variable that can be calculated later
            [datetime]$CreationDate = ($WSecNoneCriticalUpdate).CreationDate
            ##If the update is more than 27 day old it will approve
            If ($CreationDate -le (Get-Date).AddDays(-27)) {
                switch ($answer){
                    0 {$WSecNoneCriticalUpdate.Approve('Install',$group);$msgApproved = $msgApproved + $WSecNoneCriticalUpdate.SecurityBulletins + "`t" + $WSecNoneCriticalUpdate.MsrcSeverity + "`t" + $WSecNoneCriticalUpdate.Title + "`n";break}
                    1 {$msgApproved = $msgApproved + $WSecNoneCriticalUpdate.SecurityBulletins + "`t" + $WSecNoneCriticalUpdate.MsrcSeverity + "`t" + $WSecNoneCriticalUpdate.Title + "`n";break}
                }
            }
    }elseif ($WSecNoneCriticalUpdate.LegacyName -like "*x86*" -and $WSecNoneCriticalUpdate.ProductTitles -like "*2003*") {
        ##Getting the createdate of each update and storing it in a variable that can be calculated later
        [datetime]$CreationDate = ($WSecNoneCriticalUpdate).CreationDate
        ##If the update is more than 27 day old it will approve
        If ($CreationDate -le (Get-Date).AddDays(-27)) {
            switch ($answer){
                    0 {$WSecNoneCriticalUpdate.Approve('Install',$group);$msgApproved = $msgApproved + $WSecNoneCriticalUpdate.SecurityBulletins + "`t" + $WSecNoneCriticalUpdate.MsrcSeverity + "`t" + $WSecNoneCriticalUpdate.Title + "`n";break}
                    1 {$msgApproved = $msgApproved + $WSecNoneCriticalUpdate.SecurityBulletins + "`t" + $WSecNoneCriticalUpdate.MsrcSeverity + "`t" + $WSecNoneCriticalUpdate.Title + "`n";break}
            }
        }
    }else {
        switch ($answer){
            0 {$WSecNoneCriticalUpdate.Decline(); $msgDeclined = $msgDeclined + $WSecNoneCriticalUpdate.SecurityBulletins + "`t" + $WSecNoneCriticalUpdate.MsrcSeverity + "`t" + $WSecNoneCriticalUpdate.Title + "`n";break}
            1 {$msgDeclined = $msgDeclined + $WSecNoneCriticalUpdate.SecurityBulletins + "`t" + $WSecNoneCriticalUpdate.MsrcSeverity + "`t" + $WSecNoneCriticalUpdate.Title + "`n";break}
        }
    }
}
########################################
#Windows Recommended Updates 1 month old
########################################
##Revise list of unapproved updates
$updates = $wsus.GetUpdates()  | where {$_.IsApproved -eq $False -and $_.IsDeclined -eq $False}
##Retrive a subset of updates that are updates and are of the windows family
$WRecommendedUpdates = $updates | where {$_.UpdateClassificationTitle -eq 'Updates' -and $_.ProductFamilyTitles -like 'Windows'}
Foreach ($WRecommendedUpdate in $WRecommendedUpdates) {
    If ($WRecommendedUpdate.LegacyName -like "*x64*" -and ($WRecommendedUpdate.ProductTitles -like "*2008*") -or ($WRecommendedUpdate.ProductTitles -like "*2012 R2*")) {
        ##Getting the createdate of each update and storing it in a variable that can be calculated later
        [datetime]$CreationDate = ($WRecommendedUpdate).CreationDate
        ##If the update is more than 27 day old it will approve
        If ($CreationDate -le (Get-Date).AddDays(-27)) {
            switch ($answer) {
                0 {$WRecommendedUpdate.Approve('Install',$group); $msgApproved = $msgApproved + $WRecommendedUpdate.SecurityBulletins + "`t      " + $WRecommendedUpdate.MsrcSeverity + "`t" +  $WRecommendedUpdate.Title + "`n";break}
                1 {$msgApproved = $msgApproved + $WRecommendedUpdate.SecurityBulletins + "`t      " + $WRecommendedUpdate.MsrcSeverity + "`t" +  $WRecommendedUpdate.Title + "`n";break}
            }
        }
    }elseif ($WRecommendedUpdate.LegacyName -like "*x86*" -and $WRecommendedUpdate.ProductTitles -like "*2003*") {
        ##Getting the createdate of each update and storing it in a variable that can be calculated later
        [datetime]$CreationDate = ($WRecommendedUpdate).CreationDate
        ##If the update is more than 27 day old it will approve
        If ($CreationDate -le (Get-Date).AddDays(-27)) {
            switch ($answer) {
                0 {$WRecommendedUpdate.Approve('Install',$group); $msgApproved = $msgApproved + $WRecommendedUpdate.SecurityBulletins + "`t      " + $WRecommendedUpdate.MsrcSeverity + "`t" +  $WRecommendedUpdate.Title + "`n";break}
                1 {$msgApproved = $msgApproved + $WRecommendedUpdate.SecurityBulletins + "`t      " + $WRecommendedUpdate.MsrcSeverity + "`t" +  $WRecommendedUpdate.Title + "`n";break}
            }
        }
    }else {
        switch ($answer) {
            0 {$WRecommendedUpdate.Decline();  $msgDeclined = $msgDeclined + $WRecommendedUpdate.SecurityBulletins + "`t      " + $WRecommendedUpdate.MsrcSeverity + "`t" +  $WRecommendedUpdate.Title + "`n";break}
            1 {$msgDeclined = $msgDeclined + $WRecommendedUpdate.SecurityBulletins + "`t      " + $WRecommendedUpdate.MsrcSeverity + "`t" +  $WRecommendedUpdate.Title + "`n";break}
        }
    }
}
########################################
#Windows Office Updates 1 month old
########################################
##Revise list of unapproved updates
$updates = $wsus.GetUpdates()  | where {$_.IsApproved -eq $False -and $_.IsDeclined -eq $False}
##Retrive a subset of updates that are updates and are of the windows family
$WOfficeUpdates = $updates | where {($_.UpdateClassificationTitle -eq 'Updates' -or $_.UpdateClassificationTitle -eq 'Security Updates') -and $_.ProductTitles -like '*Office 2*' -and $_.Title -notlike '*Share*'}
Foreach ($WOfficeUpdate in $WOfficeUpdates) {
    [datetime]$CreationDate = ($WOfficeUpdate).CreationDate
    ##If the update is more than 27 day old it will approve
    If ($CreationDate -le (Get-Date).AddDays(-27)) {
        switch ($answer) {
            0 {$WOfficeUpdate.Approve('Install',$group); $msgApproved = $msgApproved + $WOfficeUpdate.SecurityBulletins + "`t" + $WOfficeUpdate.MsrcSeverity + "`t" +  $WOfficeUpdate.Title + "`n"; break}
            1 {$msgApproved = $msgApproved + $WOfficeUpdate.SecurityBulletins + "`t" + $WOfficeUpdate.MsrcSeverity + "`t" +  $WOfficeUpdate.Title + "`n"; break}
        }
    }
}
##Sending EMAIL
$month = get-date -Format MMMM
switch($answer){
    0 {send-mailmessage -to patchingreports@example.com -subject "Updates Approve/Declined for $month" -body "Approved Updates`n $msgApproved`nDeclined Updates`n $msgDeclined"  -smtpserver "mailserver.example.com" -from WSUSServer@example.com;break}
    1 {send-mailmessage -to patchingreports@example.com -subject "Updates Reports for $month" -body "Approved Updates`n $msgApproved`nDeclined Updates`n $msgDeclined"  -smtpserver "mailserver.example.com" -from WSUSServer@example.com;break}
}
exit

Feel free to modify this script as needed for you environment. Leave a comment if you have any questions. Have fun and happy scripting.
As always with powershell be sure your Set-ExecutionPolicy is set to remotesigned if you want the local script to run.

Coming Soon WSUS Powershell scripts

I just finished writing some powershell scripts to help you better manage your updates applied to machine on a monthly basis. I dread every patch Tuesday but it is something that is need to better protect yourself and your environment. Where I currently work, we have a very unique standard of apply patches. Security Patches that are a MRSC of critical are applied that month and everything else is applied the following month. But then there was another issue, we only have x86 of one OS and x64 of others. Then you also need to make sure that you decline the Itanium patches if you don’t have any. I needed a way to automate the approval/decline process of patches based on our standard and only approve updates need for our environment to keep WSUS more clean. I will be uploading the scripts next week. My script is only concerned with servers so you will need to modify for you environment. Thanks for your interests and have fun scripting.

Transfer Network Printers Batch file

Have you ever wanted to use wmic to retrieve a list of printer just to find out it will not list networked printers.
wmic /node:”ComputerName” printer get name
Well I ran into this issue as well.

I wanted to create a script that looked at the printers on you old machine and added them to your new one.
All of the Network Printers are stored within the registry of the computer so if you are good enough you can find a way to retieve them.
You must be sure that you have remote registry service started.

set /p tempComputerName=Please enter the computer name=
if not %tempComputerName:~0,4%==172. (
    wmic /node:"%tempComputerName%" os get csname | findstr /i "%tempComputerName%"
    if errorlevel 1 (
    echo %errorlevel%
    goto failedLookup
    )
)
for /f "tokens=* delims=" %%b in ('wmic useraccount where "name='%username%'" get sid ^| find "S-"') do set SID=%%b
for /f "tokens=3 delims=," %%c in ('reg query \\%tempComputerName%\HKU\%SID:~,-3%\Printers\Connections ^| find "print01"') do rundll32 printui.dll PrintUIEntry /in /n "\\print01\%%c"
:set default
for /f "tokens=3 delims= " %%d in ('reg query "\\%tempComputerName%\HKU\%SID:~,-3%\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v Device ^| find "print01"') do set fullString=%%d
set endString=%fullString:*,=%
call set defaultPrinter=%%fullString:%endString%=%%
rundll32 printui.dll PrintUIEntry /y /n "%defaultPrinter:~,-1%"
goto end
:failedLookup
cls
echo The computer that you specificied is either off or has an old dns record.  If possible please specify the IP address.
goto end
:end
pause
exit

I Commented out some descriptions so you know what was happening.
Feel free to modify and change as needed.
Have Fun.

Suggestions?

It has been a while since I have needed to create anything new as far as scripting. I want to get into more powershell scripting. Right now I am decently versed in batch/cmd script.

If you have any ideas or anything that you do manually within your company/environment let me know what it is. Provide a quick description of your scenario. I will evaluate all the suggestions and take one/or some and TRY to develop a script for it.

Thanks for all your feed back.

Change exchange calendar permissions with Powershell

The president of our company wants access to view all of his direct reports’ calendars.

Option 1 go to each individual users computer, open outlook, and set calendar permission. (The issue with this is you may not know their passwords, or finding the free time to do it.)

Option 2 run this powershell script

#Test if you have the Exchange Management Console installed.
if (test-path -path "C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1"){}
else {write-host "You must have the Exchange Management Console installed on your computer."
	$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	exit}
#Auto launch and connect to Exchange
. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto
$tempUsernameMailbox = read-host "Please enter the username of the Calendar you wish to edit      "
$tempUsernameAccess = read-host "Please enter the username of the User you want to have access to"
$AccessPermissions = read-host "What level of access would you like the user to have?(E)ditor, (R)eviewer, or (D)elete/Remove. ('e' 'r' 'd')?"
#Set readable permissions
if ($AccessPermissions -eq "e"){$AccessPermissionsRead = "Editor"}
	elseif ($AccessPermissions -eq "r"){$AccessPermissionsRead = "Reviewer"}
	elseif ($AccessPermissions -eq "d"){$AccessPermissionsRead = "Remove"}
else {write-host "Please specify a valid permission character"
	$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	exit}
write-host "You are about to give $tempUsernameAccess $AccessPermissionsRead permissions to $tempUsernameMailbox Calendar."
write-host "Press any key to continue . . ."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
switch ($AccessPermissions){
	e{add-MailboxFolderPermission -Identity $tempUsernameMailbox":\Calendar" -User $tempUsernameAccess -Accessrights editor}
	r{add-MailboxFolderPermission -Identity $tempUsernameMailbox":\Calendar" -User $tempUsernameAccess -Accessrights reviewer}
	d{remove-mailboxfolderpermission -Identity $tempUsernameMailbox":\calendar" -user $tempUsernameAccess}
}
write-host "Press any key to continue . . ."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit

Have fun, feel free to modify or add more permission sets for your company. This should work on your exchange server or if your computer has the Exchange Management Console. Remember this is a powershell script so you will need to install powershell if you are on XP. I have only tested with Windows 7.

Let end user log off from server batch script

We had a user who was messing with a new piece of software on a server. Multiple times a day the program would get stuck in a loop and they would have to call IT to force logoff there session.

After about three times of this I decided to come up with a script so they could do it themselves.

:Let user logoff stuck session on Server
set /p tempserver=Please specify the server name:
set /p tempusername=Please specify the username   :
quser /server:%tempserver% | find "%tempusername%"
if %errorlevel%==1 goto UserNotLoggedOn
for /f "tokens=3" %%j in ('quser /server:%tempserver% ^| find "%tempusername%"') do set SessionID=%%j
logoff /server:%tempserver% %sessionID% /v
pause
exit
:UserNotLoggedOn
@echo the user you have specified is not logged on to %tempserver%
pause
exit

Keep in mind I do not know if quser will work on XP.

Update “Hide User From GAL” with a batch script.

Here is a neat way to hide a user from Global Address List without having to go into Exchange. I just figured this one out the other day. I comes in handing when terminating employees.

:Hide user from GAL
:start
echo off
cls
set /p tempusername=What username would you like to hide?
dsquery.exe user OU=Employees,DC=ABCCompany,DC=com -o dn -scope subtree -samid %tempUsername% -d SSC | findstr /r "CN="
if %errorlevel%==1 goto UserNoExist
@echo --------------------------------------------------------------------------------
@echo Hiding %tempusername%?
@echo Is this correct?
pause
cls
for /f "tokens=*" %%h in ('ldifde -f %temp%\hideExch.ldf -d "ou=Employees,dc=ABCCompany,dc=com" -p subtree -r "(&(objectCategory=person)(objectClass=User)(sAMAccountName=%tempusername%))" -l "DN" -v ^| find "entry"') do set ldifdeDNNAME=%%h
echo dn: %ldifdeDNNAME:~17%>%TEMP%\hideExch.ldf
echo changetype: modify>>%TEMP%\hideExch.ldf
echo replace: msExchHideFromAddressLists>>%TEMP%\hideExch.ldf
echo msExchHideFromAddressLists: TRUE>>%TEMP%\hideExch.ldf
echo ->>%TEMP%\hideExch.ldf
echo delete: showInAddressBook>>%TEMP%\hideExch.ldf
echo ->>%TEMP%\hideExch.ldf
ldifde -i -f %TEMP%\hideExch.ldf
del %TEMP%\hideExch.ldf
exit
:UserNoExist
cls
echo The user you have specified does not exist in AD.
pause
goto start

There you go. Feel free to modify as needed so it fits your environment.

Batch file for termination (Update)

Want a batch file that will terminate a user based on there username. Here it is.

:start
echo off
title termination.bat
cls
echo This batch file will terminate employees based on username.  This script will   do all of the following:
echo 1) Disable AD account (any active sessions will NOT be terminated)
echo 2) Remove all groups containing with "d_ vpn ctx citrix"
echo 3) Delete their IP telephone number
echo 4) Hides email from GAL
echo 5) Move AD account into the Terminated Employees OU
echo 6) Move there H: Drive to \\SERVER\homedirs$\!terminatedEmployeesHDrive\
pause
set /p tempusername=What username would you like to terminate?
cls
@echo Terminate %tempusername%?
dsquery.exe user OU=Employees,DC=ABCCompany,DC=com -o dn -scope subtree -samid %tempUsername% -d SSC | findstr /r "CN="
if %errorlevel%==1 goto UserNoExist
@echo --------------------------------------------------------------------------------
@echo Is this correct?
pause
cls
echo Terminating %tempusername%
@echo--------------------------------------------------------------------------------
::Disable AD account
net user %tempusername% /active:no /DOMAIN
for /f "tokens=*" %%a in ('"dsquery.exe user OU=Employees,DC=ABCCompany,DC=com -o dn -scope subtree -samid %tempusername% -d SSC"') do set dnName=%%a
::Remove all groups containing with "d_ vpn ctx xitrix"
for /f "tokens=*" %%b in ('dsget user %dnName% -memberof ^| findstr /i /r "d_ vpn ctx citrix"') do dsmod group %%b -rmmbr %dnName%
::Set ipTel variable
for /f "skip=1 delims=dsget" %%a in ('dsget user %dnName% -iptel ^| find "  "') do set ipTel=%%a
:CheckIPPhone
echo %ipTel%|findstr /r "[0-9]"
if %errorlevel%==1 goto :HasNoIPPhone
set IPPhoneMessage=The IP phone number associated with %tempusername% is %ipTel:~2,4%. It is documented at G:\IS\PhoneNumbers\PhoneNumbers.csv
for /f "tokens=* skip=1" %%b in ('DSGET user %dnName% -fn ^| find "  "') do set firstName=%%b
for /f "tokens=* skip=1" %%b in ('DSGET user %dnName% -ln ^| find "  "') do set lastName=%%b
for /f "tokens=* skip=1" %%b in ('DSGET user %dnName% -title ^| find "  "') do set title=%%b
if %ipTel:~3,1%==5 (set location=Plant1
	goto IPPhoneDocument
	)
if %ipTel:~3,1%==7 (set location=Plant1
	goto IPPhoneDocument
	)
if %ipTel:~3,1%==6 (set location=Plant2
	goto IPPhoneDocument
	)
set location=Unknown
:IPPhoneDocument
echo `%ipTel:~2,4%,%firstName%%lastName%,%title%,%location%>>G:\IT\PhoneNumbers\PhoneNumbers.csv
goto IPPhoneCheckEnd
:HasNoIPPhone
set IPPhoneMessage=The user %tempusername% has no IP Phone.
:IPPhoneCheckEnd
::Delete ipTel from AD
dsmod user %dnName% -c -iptel ""
::Hide user from GAL
for /f "tokens=*" %%h in ('ldifde -f %temp%\hideExch.ldf -d "ou=Employees,dc=ABCCompany,dc=com" -p subtree -r "(&(objectCategory=person)(objectClass=User)(sAMAccountName=%tempusername%))" -l "DN" -v ^| find "entry"') do set ldifdeDNNAME=%%h
echo dn: %ldifdeDNNAME:~17%>%TEMP%\hideExch.ldf
echo changetype: modify>>%TEMP%\hideExch.ldf
echo replace: msExchHideFromAddressLists>>%TEMP%\hideExch.ldf
echo msExchHideFromAddressLists: TRUE>>%TEMP%\hideExch.ldf
echo ->>%TEMP%\hideExch.ldf
echo delete: showInAddressBook>>%TEMP%\hideExch.ldf
echo ->>%TEMP%\hideExch.ldf
ldifde -i -f %TEMP%\hideExch.ldf
::Delete ldf after import
del %TEMP%\hideExch.ldf
::Move user to Terminated Employees OU
dsmove %dnName% -newparent "OU=Terminated Employees,OU=Employees,DC=ABCCompany,DC=com"
::Check home directory, move to !terminatedEmployeesHDrive folder
if exist "\\server1\homedirs$\%tempusername%" goto server1
if exist "\\server2\d$\homedir\%tempusername%" goto server2
if exist "\\server3\d$\HomeDir\%tempusername%" goto server3
set homedirMessage=%tempusername% did not have an H: Drive
goto end
:server1
move /y "\\server1\homedirs$\%tempusername%" "\\server1\homedirs$\!terminatedEmployeesHDrive\"
set homedirMessage=%tempusername% H: Drive was located on server1. Verify that the folder has been moved  to the !terminatedEmployeesHDrive folder.
goto end
:server2
move /y "\\server2\d$\homedir\%tempusername%" "\\server2\d$\homedir\!terminatedEmployeesHDrive\"
set homedirMessage=%tempusername% H: Drive was located on server2. Verify that the folder has been moved  to the !terminatedEmployeesHDrive folder.
goto end
:server3
move /y "\\server3\d$\HomeDir\%tempusername%" "\\server3\d$\HomeDir\!terminatedEmployeesHDrive\"
set homedirMessage=%tempusername% H: Drive was located on server3. Verify that the folder has been moved  to the !terminatedEmployeesHDrive folder.
goto end
:end
echo --------------------------------------------------------------------------------
echo Please verify that all of the outputs above were successful.
echo --------------------------------------------------------------------------------
echo %homedirMessage%
echo.
echo %IPPhoneMessage%
echo.
echo List of additonal steps.
echo 1) Step one
echo 2) Step two
echo 3) Step three
echo.
echo --------------------------------------------------------------------------------
pause
exit
:UserNoExist
cls
echo The user you have specified does not exist in AD.
pause
goto start

This was really tough to create I hope others can use it and manipulate it as needed. Have FUN.

VBS on specific computers

Want to have a login script that runs on all computers but you still want to omit servers?

Here is something I came up with.

Dim strOS
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
'    Wscript.Echo objOperatingSystem.Caption & _
'    "  " & objOperatingSystem.Version
strOS = objOperatingSystem.Caption
Next

exists = InStr (strOS, "Server")
If exists = 0 Then
	'Run the script for Workstations or SKIP
Else
	'Run the script for Servers or SKIP
End If

This will detect if the string/word Server is in the OS name. Run as needed hope this helps

Registy scanning and adding keys

For my next scripting project and am going to work on scanning the registry of the local computer for a key or value. If it already has it, it will skip. If it does not have it, it will either run a .reg or add the key with a vbs.

Hope to have it posted within the next couple weeks.