Friday, 20 January 2012

Resolving Active Directory Account Lockouts


Account lockouts can be a real pain to fix if you don't know where the lock is coming from. In these days of mobile computing very few users restrict themselves to a single PC or device. Often IT departments have to allow multiple devices to utilise the same user account credentials whether that be on the company Desktops, Laptops, Smartphones or even home user equipment. The problem is that when you have so many devices it gets a bit tricky to see where the lock has come from and users inevitably begin to think there may be some kind of conspiracy against them when their account keeps locking; even if it is their fault!

Tools Required


To perform all steps in this guide you will require a few tools:
A PC with Admin Pack installed (for Active Directory access) and Acctinfo.dll installed
(http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=18465)


Causes of Account Lockouts

The most obvious scenario is that the user is continuously inputting the incorrect username/password combination - but that's far to easy. Other scenarios include:


  • The user has changed passwords once they have logged on but have not logged back on again to re-sync their account.
  • A stored username/password in a program, perhaps one that requires separate proxy authentication is requesting access to the Internet and supplying an incorrect password.
  • A third party device, such as an Iphone connecting to webmail via RPC over HTTP with the incorrect password stored.
  • The user has mapped a network drive on a different machine using their credentials and choose “Save Password” option, which has now expired.
  • A scheduled task running with an invalid password.


Finding Where the Account Lockout Originated

The first thing is to make sure you know where the account lockout is coming from. Use Active directory with the ACCTINFO.DLL tab and check the time of the last “bad logon”.



Clicking on “Account Lockout Status” will bring up a list of domain controllers, allowing you to ascertain which domain controller the user locked out on first.





Right click the domain controller the account locked out on and choose event viewer, then organise by user and click on the username. You will see a "Failure Audit" at the time of lockout.


 
You will then be given the name of the machine the account has locked out on as well as an Idea what program may have caused the lock, see “Logon attempt by” field.





Sometimes this can be a very generic system process which will result in you having to perform further troubleshooting steps on the user’s machine.


Finding the Cause of the Lockout on the User Machine


Finding the cause of account lockouts on the local machine can be quite difficult due to the number of potential causes of this problem but some general advice is as follows:


  • Clean out the Temporary Internet Files and stored passwords in Internet Explorer.
  • Clean out the windows credential manager by running "Control keymgr.dll" from the run prompt and deleting all stored passwords.
  • Check the users “My Computer” for drive mappings created by the user; if there is anything out of the ordinary remove the mapping.
  • Check for unusual software that may require individual proxy server configurations such as Google Earth, or any programs that perform periodic updates.



Drastic Measures if you still can't find the lock


From the Account lockout tools copy alockout.dll to the user’s c:\Windows\System32 folder. Remotely connect to the users registry using regedit and navigate to this key:


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Windows


Create a new REG_SZ key called "AppInit_DLLs" and set its value to “alockout.dll"




Now restart the PC and wait for the account to lock out again. Once it locks check the C:\WINDOWS\Debug folder for a file called “Alockout.LOG”.

If you open this file with Notepad you should see a list of applications which attempted to pass network credentials along with details on which was successful and which failed. Check what time the users account locked out in ACCTINFO.DLL and the look for the corresponding entry on the list, this will be the application causing the problem.

The final step is to find this application on the user’s computer and find a way to either remove the cached credentials or in worst case scenario it may be necessary to remove the program all-together.

Sunday, 8 January 2012

SCCM Operating System Deployment Task Sequences

In  the past few months my business has been working on the move away from XP/Altiris to a Windows7/SCCM 2007R3 environment. I was working closely with an outside contractor to get the infrastructure in place and getting SCCM up and running, but before this was even completed I was tasked to begin considering how to perform operating system deployment (OSD). Looking at SCCM from a newbie perspective I will talk about the challenges I faced in getting my OSD to work successfully.

After some investigation I soon found out that SCCM offers multiple ways to deploy an operating system to new machines and also machines already on your network. So far I have tested and implemented the following:

  • PXE boot environment with unknown computer support - I have put a password on this at the moment so that users can't unknowingly image a newly added machine. This is useful where you might be in a scenario where you unbox and build multiple machines at one time, you really don't want to be messing around writing down MAC addresses to import for hundreds of PCS at a time.

  • Bootable WinPE CD/USB stick, this method means you don't have to enable a PXE server on the network and is useful in environments like mine that already have multiple PXE servers. Unfortunately this means you will have to manually import the machine MAC address and put it into the OSD collection before it can be installed.  The disadvantage here is that you end up with a duplicate system in SCCM once it is renamed, but providing you have scavenging set up it should disappear reasonably quickly.

  • If the PC you image is an existing PC with a previous OS (WinXP) you can simply for an install of the SCCM Client and then put the machine into the OSD collection. This can be very handy, but again it will create a duplicate machine in SCCM, which will be marked as "obsolete". This appears to be by design to avoid endless build cycles.

  • Stand-alone task sequence media on CD/USB stick for the entire task sequence onto a DVD - this method works well for remote/small offices that don't have any server infrastructure, but SCCM task sequences can be rather large, in my case I need 3 DVDs worth to fit my standard image. It looks like high capacity USB flash drives are more feasible in this scenario.
Task sequence media is easily created, simply go to "Operating System Deployment" > "Task Sequences" > select your OSD task sequence and click "Create Task Sequence Media"


You can then select the type of media to create or create an ISO of the image for later use. Coming from an Altiris background I have to say I was very impressed easy this was and how well this solution worked.


I've got ahead of myself a little bit here, the largest part of this was the creation of the task sequence to begin with. I was fortunate that I had a base Windows 7 install.wim. Unfortunately it had only been tested on a handful of different models of PCS. After an evaluation of my asset management database I found that I actually had 11 distinct types of desktops that would support Windows7 in my environment. At this point I got a bit of headache, thinking back to Altiris and the multiple images for Windows XP. I wanted to get away from this and have "one image to rule them all".

One Image to Rule them All

The first thing I did was to test my Boot.wim with each device to ensure two things:
  1. Each device could successfully boot to WinPE image.
  2. By pressing F8 during PE boot and using the command prompt I could verify that WinPE could see the Hard Disk Drive and Network Card.
Fortunately all devices booted to WinPE without issue, but some were missing the network card driver or storage controller. These would have to be injected to the Boot.wim before we could continue. This can either be done by mounting the image using DISM in Microsoft MDT2010, or in SCCM you can go to "Boot Images" > right click on your boot.wim and go to properties, then press the "Windows PE" tab, press the "Sun" icon and then select the drivers you want to be injected. In order for the drivers to appear on this list you will have to firstly import them.


Now I had a working preinstall environment I could then begin testing deploying my main image. The next thing I done was to visit the manufacturer websites and download all existing drivers for the products I wanted to move to Windows 7. I downloaded the drivers for eleven models in total and stored them neatly on my SCCM server, sorting by model and device type. I then had another decision to make.

Order Vs Chaos

After some research it would appear there are two ways to approach driver management. One being "Chaos" whereby you simply import every driver possible and then allow every machine being built to scan then entire available driver database.  The "Order" solution is a very controlled environment whereby you import drivers for each model into a package and apply only that specific package to its relevant model. Being lazy I liked the sound of Chaos, but In practice I found this method to be much slower at building machines; the more drivers there are available the longer Windows takes to sort through and determine which driver is the most suitable.


Fortunately, SCCM makes importing drivers very easy. Simply create a new folder in the drivers section, right click, select import and browse to the location you stored the drivers for that specific model.

I was surprised to find that even when you select x64 drivers only that the packages also seem to contain XP, Vista, x86 drivers too. If you are going to import the packages for an x64 image like mine make sure to remove these drivers.


Either click new package to create a specific package or select an existing package, ensure to tick "Update distribution points when finished" to ensure your drivers get sent to PXE for immediate use.


Trying to adopt the "Order" method was causing me to run into issues. SCCM doesn't like it when you try to import a duplicate driver. It turns out that it's quite common for several HP laptops and desktops to share the exact same hardware, this was causing an error when trying to import this driver even although I just wanted to put that driver into my specific machine package. To get around this I installed patch KB2213600 which will allow SCCM to import duplicates.

With this method I was left with eleven different driver packages which I could apply. The next question would undoubtedly be how does SCCM know to apply that specific driver package? 


Using  a WMI query to select the model name from the system bios as a condition for installation allows only this package to be installed.


It's not only drivers that benefit from this functionality, what about the differences in software between laptops and desktops? You won't want to install certain software such as a VPN client or a mobile connectivity suite on your desktops!  Luckily there are a couple of easy ways around this.

Below shows and example using the "IsLaptop" variable - note that this is only availble when you have MDT integration. Before checking for this variable you will need to perform a "Use Toolkit Package" and  a "Gather" from the MDT menu. 

This also seems to work bothways. IE you can use "isDesktop"



You can also check for the presence of a battery.



Hardware Based Applications

When I had created all my packages and performed some test builds I noticed that there were some systems that just wouldn't install the drivers without its accompanying piece of software. ATI and Nvidia graphics packages seem to be the worst culprits, as both rely on their "Catalyst control centre" and "Nvidia Control Panel" to offer any advanced functionality. Bluetooth drivers were also the same as each device requires its own custom Bluetooth stack. I read elsewhere that these types of programs were called "Hardware based applications" being that they blur the lines between drivers and software. I found the simplest way to deal with these is to treat them like any other piece of software. Referring to the suppliers documentation *cough* and after fiddling about I found all the required silent install switches.

So far I'm about 90% there towards finalising the build. There are always little tweaks to go back and add. The other big part of this will be a brand Active Directory/Group policy re-structure which will go a long way to configuring this build. I don't want to add too many registry fixes into the build, but inevitably these will keep coming. At this point my OSD task sequence looks like this.




Please note that grey items are currently disabled experimental steps I was toying with. In the end I don't think I really need these. Using the above I can perform a zero touch installation on a new out-of-box PC or reimage an existing machine by simply dropping the PC into the OSD collection.

Like I said, I'm still an SCCM newbie and I would appreciate any advice on improving this.

Andrew



      Tuesday, 20 December 2011

      A modular approch to Altiris Deployment Console Software Installs.


      One thing that always annoyed me about Altiris was that when working with multiple servers there was no way to load balance or route traffic based upon the closest server, instead Altiris would try and push everything from the central site. The work-around is that you would have to create multiple jobs for the one piece of software which can get very tedious, is prone to human error and generally looks very messy in your deployment console! Thanks to the scheduling features in Altiris publishing smaller applications wasn't such a big deal even if your WAN link wasn't great, but when you have to deploy something as big as Office 2010 you begin to appreciate the scale of the problem. In this post I will show you my method of dynamically mapping to the closest server and take on a modular approach which you can use time-and-again in all your deployment jobs.

      It all starts with a good drive mapping script


      As I mentioned previously, informing the Altiris server to use the closest distribution point instead of one that is potentially hundreds of miles away can't be achieved using the standard "Add copy file job". Instead we turn to VBscript.


      The script below will do the following tasks:
      1. Inform the client to ping a list of Altiris servers
      2. Clear the required drive letter on the client PC (W: in this example)
      3. Map a drive letter to the closest Altiris distribution point based upon ping response time.
      4. If the user is logged on it will use the users credentials to map the drive.
      5. If no user is logged on it will use a system account.

      ' Drive mapping script by Andrew Allison 07/06/2011
      ' Pings all Altris servers in the array and maps a drive as w: to the one with lowest response time
      ' if user is logged on uses user credentials to map drive, if no uses domain account specified in uzername variable
      '****************************************************************************************************


      'array holding list of altiris distribution servers
      Dim arr : arr = Array( "server1" , "server2" , "server3" , "server4" , "server5" )
      Dim out
      Call ServersByPingTime( arr , out , True )
      Dim s
      'WScript.Echo "In order fastest to slowest: "
      For Each S in out
      'WScript.Echo s
      'document.write(s(0))
      Next
      'WScript.Echo(out(0))
      lowestping =(out(0))
      'wscript.echo lowestping

      strComputer = "."
      Set objWMIService = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
      Set colComputer = objWMIService.ExecQuery _
      ("Select * from Win32_ComputerSystem")
      For Each objComputer in colComputer
      'Wscript.Echo objComputer.UserName
      If IsNull(objComputer.UserName) Then 'If no one is logged on
              strLoggedOn = "No"
          Else
              strLoggedOn = "Yes"
          End If
      'wscript.echo strLoggedOn
      Next


      Dim objNetwork
      Dim strDriveLetter, strRemotePath
      Dim u_name_pserver, p_word_pserver
      Dim strProfile
      Dim uzername
      Dim p4ssword


      'specifies domain account to use to map the drive in the event no user is currently logged on
      uzername="yourdomain\domainadminaccount" 
      p4ssword="youraccountpasword"
      strProfile = "true"

      'specifies drive letter to use
      strDriveLetter = "w:"
      'specifies the servername and path to distribution share
      strRemotePath = "\\"& lowestping &"\yourshare"

      on error resume next
      Set objNetwork = CreateObject("WScript.Network")
      'if no user logged on then remove the drive letter in case it is currently mapped to somewhere else
      If strLoggedOn = "No" then
      objNetwork.RemoveNetworkDrive strDriveLetter
      wscript.sleep 5000

      'map the drive letter using domain account
      objNetwork.MapNetworkDrive strDriveLetter, strRemotePath, strprofile, uzername, p4ssword
      Else

      'map the drive using the users current credentials
      objNetwork.RemoveNetworkDrive strDriveLetter
      wscript.sleep 5000
      objNetwork.MapNetworkDrive strDriveLetter, strRemotePath
      end if

      ' Begin pinging all servers and sort by fastest response time
      Function Ping(strHost , ByRef bytesSent , ByRef bytesReceived , _
               ByRef bytesLost , ByRef minMs , ByRef maxMs , ByRef aveMs )
       Ping = False
       Dim objShell, objExec, strPingResults, bRet
       Set objShell = CreateObject("WScript.Shell")
       Set objExec = objShell.Exec("ping -n 1 " & strHost)
       Do
           WScript.Sleep 100
       Loop Until objExec.Status <> 0
       strPingResults = objExec.StdOut.ReadAll
       Dim regexpingstats : Set regexpingstats = new regexp
        regexpingstats.Pattern = "Packets:\s+Sent\s+=\s+([0-9]+).*Received" & _
                                 "\s+=\s+([0-9]+).*Lost\s+=\s+([0-9]+)(?:.*\s)+" & _
                                 "Minimum\s+=\s+([0-9]+)ms.*Maximum\s+=\s+" & _
                                 "([0-9]+)ms.*Average\s+=\s+([0-9]+)ms"
       regexpingstats.Global = True
       regexpingstats.IgnoreCase = True
       regexpingstats.MultiLine = True
       If regexpingstats.Test(strPingResults) Then
        Dim m : Set m = regexpingstats.Execute(strPingResults)
        bytesSent = CInt(m.Item(0).subMatches.Item(0))
        bytesReceived = CInt(m.Item(0).subMatches.Item(1))
        bytesLost = CInt(m.Item(0).subMatches.Item(2))
        minMs = CInt(m.Item(0).subMatches.Item(3))
        maxMs = CInt(m.Item(0).subMatches.Item(4))
        aveMs = CInt(m.Item(0).subMatches.Item(5))
        Ping = Eval( bytesSent > bytesLost )
       End If
      End Function

      'Returns false if no server were found alive
      'outSortedByMs - array sorted fastest response to slowest response time
      Public Function ServersByPingTime( ByVal inSeverList , _
                      ByRef outSortedByMs , bVerbose )
        On Error Resume Next
        ServersByPingTime = False
        outLivingSorted = Array
        Dim s, i , j , temp
        If bVerbose Then
        For Each s In inSeverList
         If bVerbose Then wscript.StdOut.Write("        Server: " & s )
         Dim bs, br, bl, mi , ma , av
         If Ping( s , bs, br, bl, mi , ma , av ) Then
          If bVerbose Then
           'WScript.Echo(" [Passed]")
           'WScript.Echo("    Bytes Sent: " & bs )
           'WScript.Echo("    Bytes Recv: " & br )
           'WScript.Echo("    Bytes Lost: " & bl )
           'WScript.Echo("        Min ms: " & mi )
           'WScript.Echo("        Max ms: " & ma )
           'WScript.Echo("    Average ms: " & av )
          End If
          i = UBound(outLivingSorted) + 1 
          ReDim Preserve outLivingSorted(i)
          outLivingSorted(i) = Array(s,av)
          ServersByPingTime = True ' Success there are servers alive...
         Else
          If bVerbose Then
          ' WScript.Echo(" [Failed]")
          ' WScript.Echo("")
          End if
         End If
        Next
        'Sort...
        For i = UBound(outLivingSorted) - 1 To 0 Step -1
          For j = 0 To i
            If outLivingSorted(j)(1) > outLivingSorted(j+1)(1) Then
               temp=outLivingSorted(j+1)
               outLivingSorted(j+1)=outLivingSorted(j)
               outLivingSorted(j)=temp
            End If
          Next
        Next

        'Temp array to store the new pinged and sorted by reponse time...
        Dim temparray
        ReDim temparray(UBound(outLivingSorted))
        For i = 0 To UBound(outLivingSorted)
          temparray(i) = outLivingSorted(i)(0)
        Next
        outSortedByMs = temparray
      end if
      End Function
      wscript.quit



      Copy the files down to the local PC

      You probably are wondering why not just use the built in "Copy File to" function in Altiris? Well I've tested this with not really much success. If you specify a drive letter in this function for Altiris to use it will think that W: is in fact a local drive in the Altiris server. You can't specify UNC as this will defeat the purpose of the above script.


      I find that my installers behave themselves much better when the are copied to the PC first before installing, using my method here creates a little layer of complexity, as you will require to synchronise the content on all Altiris servers, but overall it's worth it to ensure that no matter what site a machine is based in, you won't kill the WAN and the install won't take forever. Below is an example script, all it does is copy the files down, you will end up a new "copy file to" script for each app you own, ensure to save the name as something meaningful.



      'Copy Folder contents to the specified folder
      'Last update 10/08/10 by Andrew Allison

      '**************************************************
      On Error Resume Next
      dim WshShell, oShell, sCmd, i, objFSO, objFolder, strDirectory1

      Set WshShell = WScript.CreateObject("WScript.Shell")
      Set objSysInfo = CreateObject("ADSystemInfo")
      Set objNetwork = CreateObject("Wscript.Network")
      Set WshNetwork = WScript.CreateObject("WScript.Network")
      Set objShell = CreateObject("Wscript.Shell")
      Set oShell = CreateObject("Wscript.Shell")
      Set WshEnv = WshShell.Environment("PROCESS")
      Set objFSO = CreateObject("Scripting.FileSystemObject")

      Const OverWriteFiles = True
      strComputer = "."

      'Creates the Support Directory on the C drive
       strDirectory1 = "c:\support"
       Set objFSO = CreateObject("Scripting.FileSystemObject")
       Set objFolder = objFSO.CreateFolder(strDirectory1)

      ' Disables the Open File security warning.
      WshEnv("SEE_MASK_NOZONECHECKS") = 1

       objFSO.CopyFolder "W:\yourfolder" , "C:\support\yourfolder\" , OverWriteFiles

      i = oShell.Run(sCmd,1,true)
      ' Enables the Open File security warning again.
      WshEnv.Remove("SEE_MASK_NOZONECHECKS")

      wscript.Quit

       

      Send the Install command

      The installation command will obviously be different depending the program and installation package type. MSI files are generally much easier to work with than most others. There is not really any benefit of having this part in as VBscript, although it is entirely possible. I have to admit that usually I just use the "Run Script" command in Altiris and then type in the install string and full path to the "c:\support" directory.






      Clean up the drive letter

      After the install has been completed you will always want to ensure you remove the drive letter. You don't really want your users snooping around on your distribution points.

      Option Explicit
      on error resume next
      Dim objShell, objNetwork, DriveLetter1

      DriveLetter1 = "w:"
      Set objShell = CreateObject("WScript.Shell")
      Set objNetwork = CreateObject("WScript.Network")

      objNetwork.RemoveNetworkDrive DriveLetter1
      Wscript.Quit


      The whole process looks a little like this for each deployment job. This example  is Autodesk DWG Trueview, the "run script" sections below represent many prerequisite software installations. Luckily you can simply run one after another.

      Sunday, 18 December 2011

      Installing Exchange System Manager for Windows Vista on Windows 7 x64

      Like many companies mine has not yet got around to upgrading to Exchange 2007 or 2010. When you want to encourage the move to a full Windows 7 environment this can be an issue as there are no management tools available for this older version of Exchange. The last thing you want is to have all admins logging onto the server to check simple things such as tiers, configure addresses etc.

      Luckily Microsoft did release Exchange System Manager for Windows Vista - but a badly configured MSI means that you won't be able to install this on Windows 7.




      Even when attempting to run the program in compatibility mode you are still greeted with the same unfriendly error message.


      Fortunately I found a way around this. You will require to install an MSI editor such as InstEd or Orca. I personally prefer InstEd as it has many more features. Simply open up the MSI in InstEd and navigate to "InstallUISequence" and select the "CA_SET_ERROR_MSG" and "FatalErrorDialog" entries, right click and choose "Delete Rows".



      You can now click "File" > "Save as" > "ESMVISTA_FIXED.MSI". You should now be able to run the installer without any annoying warnings. I have tested this over the last few weeks and it works flawlessly.

      
      Ah - good old T&C - a welcome sight.
      
      Fully installed and working
      
      As it turns out, The Exchange Management tools are not the only program affected by this issue. So far using this method I have managed to resolve issues with Cisco Unified Desktop Supervisor, Agent and Cisco Unified Desktop Administrator. The rows you have to delete are going to be a little different, but usually it's a rather obvious OS check that is pretty easy to spot. If you decide to use this tip just be sure to inform you manager that this is work-around, not a permanent fix - the moment you do this you are saying that you need no support from the supplier.

      Andrew

      Removing local admin accounts except for Jim and Bob

      As far as I can remember it's been recommended good practise to remove local administration rights from end-users PCs, but if you haven't already done this or haven't quite got everyone in your department on-board with the idea It can be a tricky business explaining to your users why you have to remove that BitTorrent client and their favourite spyware ridden game from their business machine. What about Jim and Bob, the directors of your company? Effectively it's their train set, they pay your salary and pretty much own the business. Are you really in a position to be able to tell them what they can or can't do on a company PC? Them having their own apps installed inevitably this leads to a infection where all lower-level managers below them want the same. Before you know it you become inundated with requests for questionable software to be installed and end up actually having to support it, congratulations, you now support an app you know nothing about, have no mention of it in your service catalogue and no Service Level Agreement.

      In an ideal world the best solution to this is not to allow them to install it in the first place, which is fine if you are in a position to take this firm standpoint and treat all users the same. Unfortunately a few weaker links inevitably end up making more work for you and everyone else.

      Group policy will allow you to create security groups for your elevated accounts and can also be configured to strip out other accounts from local administration groups. This is fine if everyone is on-board with the idea and you don't want to end up with several policies for different types of users.

      The solution I came up with will allow you to remove all unauthorised users accounts, both domain and local from the computer administrators group but will allow you to add your elevated accounts and have a list of exceptions that won't be removed. This means Jim and Bob and those rare but pesky applications that just won't work properly without local admin privileges can still work, and you have clear visibility of who actually has these rights.

      The script below was based on another script I found that would just remove all local admins, I've modified it to allow exceptions, and to add in the relevant elevated account groups. Keep reading for instructions on how to implement it into your environment.


      ' Remove Unapproved Local Administrators.
      ' Last update 28/10/11 by Andrew Allison
      ' vbscript


      '** check os version first
      strComputer = "."
      Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
      Set colItems = objWMI.ExecQuery("SELECT * FROM Win32_OperatingSystem",,48)
      For Each objItem in colItems
      osversion = (objItem.Caption)
      targetos=("Microsoft Windows XP Professional")
      intCompare = StrComp(osversion, targetos, vbTextCompare)
      'wscript.echo targetos
      'wscript.echo osversion
      'wscript.echo intCompare
      if intCompare = -1 Then
      wscript.echo "Do not use your standard user account to log onto servers! Use your Elevated account."
      wscript.quit
      elseif intcompare = "1" Then
      wscript.echo "Do not use your standard user account to log onto servers! Use your Elevated account."
      wscript.quit
      else
      'wscript.echo "0 - it must be good old XP - lets rock!"
      end if
      next

      '** Define Variables
          Dim PermittedAdmins' As Array
          Dim group
          Dim network
          dim fourthletterinname
       
         
      '** Define Permited Administrators List
      PermittedAdmins = Array("Administrator", "Domain Admins", "Director1", "Director2", "GPO_LAPTOP_PCADMIN", "GPO_DESKTOP_PCADMIN) '<--- Add to this Array any additional permited admins


      '** Get Local Administrator Group
          Set AdminGroup = GetObject("WinNT://./Administrators, Group")

      '** Search for Invalid Members & Remove Them
          For Each GroupMember in AdminGroup.Members
         
              Debug.WriteLine GroupMember.Name, GroupMember.Class, IsPermitedAdmin(GroupMember.Name)
         
              If Not IsPermitedAdmin(GroupMember.Name) Then
                  AdminGroup.Remove GroupMember.ADsPath
              End If
          Next

      '** Functions *****************************************************************
          Function IsPermitedAdmin(MemberName)' As Boolean
              Dim i' As Long
             
              For i = LBound(PermittedAdmins) To UBound(PermittedAdmins)
                  If UCase(MemberName) = UCase(PermittedAdmins(i)) Then
                      IsPermitedAdmin = True
                      Exit Function
                  End If
              Next
             
              IsPermitedAdmin = False
          End Function


      '**Start adding PCadmin groups
      Set wshShell = WScript.CreateObject( "WScript.Shell" )
      strComputerName = wshShell.ExpandEnvironmentStrings( "%COMPUTERNAME%" )
      Set network = CreateObject("WScript.Network")
      Set group = GetObject("WinNT://" & network.ComputerName & "/Administrators,group")
      On Error Resume Next 

      fourthletterinname = Mid(strComputerName,4,1)
      if fourthletterinname = "D" Then
      group.add("WinNT://yourdomain/GPO_DESKTOPS_PCADMIN")
      Elseif fourthletterinname = "L" Then
      group.add("WinNT://yourdomain/GPO_Laptops_PCADMIN")
      else
      'do nothing
      end if
      On Error Goto 0
      wscript.quit


      Note as per the "check OS version first"  section  you can see in the above script I have specified that this script should only run on a singular operating system, Windows XP Professional. This can be easily changed to any other operating system. The purpose of this function is that in all likelihood you don't want this script to end up running on your server operating system, although it is entirely possible to add all your local server administration accounts too. If you don't want to use the OS check, simply remove this section.

      The "Define Permitted Administrators List" section is where you will want to put in the user name of your PC Admin management groups and also your pesky exceptions. This isn't a list that will add admin groups, this is a list that the script will NOT remove.

      Another part you may want to remove or modify is the "Start adding PC admin groups" - this is the function that will insert your Active Directory PC Administration groups into the PCs local administrator group. In my environment all devices follow a strict naming convention which is SITE-MACHINETYPE-ASSETNO-USER eg: SBPD12345ALLISA the "fourth letter in name" variable is used to hold the fourth letter in the machine name, as you can see this will be either D for desktops, or L for laptops. If you only have one admin account for every type of device you can modify this to only have one group, this function just give a little more granular type of security.

      OK, now you have the script and have modified to suit your environment, but how do I deliver it onto the PCS? Group policy is the key here.

      You have two choices here, you can either apply based upon machine-based-policy or user-based-policy. There are advantages and disadvantages of both. In my environment my manager requested this be done on user policies. Create a new policy or modify an existing one and navigate to "scheduled tasks".


      Right click and create a new scheduled task. The settings here are up to you but this how I have configured mine.

      It's up to you as to where you store the script, you could in effect deliver it to each machine, or leave it on a web-server. I personally have opted to put it into the domain SYSVOL folder on my Domain Controller. Ensure that you use an account on the scheduled task with sufficient access to manage your PC admin group. I like to run set the script to run at logon to remove unwanted "tweakers" ;-)




      All of this is pointless if you fail to maintain your Active Directory PCADMIN groups, don't allow unelevated accounts to be added to these groups, the last thing you want to do is to give your director rights to install software on every PC on the network rather than just his own. Use the exclusions wisely.

      Andrew


      Thursday, 15 December 2011

      After all these years IE7 is still giving me a headache

      At the moment the company I work for is in a transitional phase between switching from our old Windows XP environment managed by Altiris Deployment Console to a new environment which will utilise Windows 7 Enterprise x64 and SCCM 2007 R3. I've been the tasked with being the technical lead on the implementation of SCCM and also have been working away on creating the Windows7 build and SCCM OSD task sequence. At the moment the build is almost finished, but there are still several issues being found by our IS pilot team. Due to the issues and the scale of the task required to ensure compatibility with older systems we are taking our time trying to get it right. The other major piece of work we have is a full Active Directory and group policy restructure, all of these things take time and require in-depth knowledge of how each department in the business will use the new software you will provide.


      Just now I'm left working with two different AD/GPO structures and two user operating systems to support and it's proving to be a headache. Luckily, one of the smartest things we did was to put a freeze on change control to the old environment, but this means that we are stuck with older software such as IE7, with no way to upgrade without breaking compatibility with older browser based add-ons and custom intranet solutions powered by Workflow on Lotus Domino. All of these issues take time to fix and our full Windows7 rollout can only be started once Workflow has been replaced by SharePoint.


      Some people who don't work for large organisations will say "Pleh! Just do the upgrade" but my business environment does not allow us to make changes on a whim. It's amazing how complicated changing something as simple as a browser plugin can be when you have 2000 users breathing down your neck if it doesn't behave exactly as it used to!


      Today the issue I had was with IE add-ons. A call came in via the service desk and they were unable to resolve. The call originally was logged as "Flash player doesn't work". The service desk had tried to install the latest version by using an Altiris job I had prepared earlier, it seemed to install fine but when the user went onto YouTube it asked them to install the latest version of Flashplayer.  It didn't take me long to check the add-ons menu and find that all add-ons are marked as disabled and marked as being "managed by your administrator". Strange, I don't remember setting that in a group policy, so I reset all IE settings to default, same issue. I went to the run prompt and started iexplore.exe in case it was running with in no-addon mode and it wasn't. I then checked the machine and user OU to see what policies had applied to the system and then checked the relevant group policy, no sign of add-ons being managed by policy. I logged off as the user and on as my domain admin account and found add-ons still disabled and greyed out. This was starting to become a head scratcher, I decided to follow a process of elimination and remove IE add-ons that may have become corrupted, after I ran out of add-ons to remove I still had the same issue - no luck! Next idea, a uninstall and reinstall of IE7, to make matters worse I am in Glasgow, Scotland and the system in in Sydney, Australia - the remote control speed is abysmal and I know that a reboot will be required to complete the IE re-configuration; this is a major problem since this was a laptop with a power on password enabled at bios level and no user available at the other end to type it in.


      At this point I delayed the reinstall/repair idea and went to the registry and mess around for 15 minutes. A quick trip to TechNet and I'm no better off, I find a key on TechNet all pointing to:


      HKLM \SOFTWARE\Policies\Microsoft\Internet Explorer\Restrictions 
      NoExtensionManagement DWORD set to 1 and not 0.

      But these settings are not present on my system. After reading a few blogs I still can't find anything so it's back to regedit. Eventually I found this key :

      HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\EXT
      Restricttolist DWORD was set to 1 when it should have been set to 0.

      Just in an instant Its working fine and I'm left wondering how the heck this could have been set to 1 in the first place, why this isn't documented anywhere? I will be really glad to see the back of IE7.

      Andrew


      Wednesday, 14 December 2011

      Welcome to my first Blog

      This is the first post of my first "real" blog. I'm afraid I'm not much of a writer, I sometimes lack the creative ability to write down exactly what I'm trying to say, so this blog will be in a simplistic language and will mainly focus on my daily misadventures in the fantastic world of IT.

      My First PC - Amstrad 1640

      Let me begin by telling you a bit about myself. I'm a 30 year old man-boy that is obsessed with any and all things that contain a microchip. I've been this way pretty much my entire life, I am interested in all aspects of computing including gaming. My first personal computer was a Commodore C64 (which I still have to this day) -I spent many nights writing programs in BASIC that hardly ever worked, but it was great fun, even then I was no programmer and this has not changed. It was 1993 that I got my first PC  which was a second-hand Amstrad 1640 HD30 with EGA graphics adaptor which was being thrown out from my mums old workplace, it couldn't do much but I used it to learn DOS, create simple programs and used my first GUI based OS called GEM. in 1995 I got my first laptop, I don't remember the exact model, but it was made by a company called Mitech and featured a monochrome screen, an amazing IBM DX2 66MHz processor, a huge 4MB of RAM, the best part was that it ran Windows 3.1 - this was my first exposure to MS Windows.
      My First GUI - GEM

      After leaving school in 1997 at 17 with next to no qualifications I still had no idea what I wanted to do with my life. I somehow managed to find a job as an administrator working for a major medical company and during this time I learned a lot of office software skills. As there was no on-site IT support I became a go-to point for office workers IT related issues.

      In 1998 I built my first custom computer with a mere £600 budget, which I was absolutely delighted with. It featured a AMD K6/2 350Mhz processor, 64MB RAM, S3 Savage3d & 3DFX Voodoo2 Video cards, 6.5GB HDD, Creative Soundblaster AWE32 and a FIC VA503+ motherboard. All of this was powered by Windows95 (which was just after 98 came out so 95 was far cheaper!). The most important aspect of this system was that it had a dedicated 56K modem! I had just joined the Internet revolution! I can't stress how much I learned on this little system, everything from Web design to home networking. It took a while, but eventually it finally clicked that I should have a job working in IT. It's amazing looking back now at how obvious this career choice was but seemed so unrealistic back then - I think I just lacked the confidence.

      My 3DFX Voodoo 2 - Awesome

      After two years of college doing my HNC and HND in Computer Support and Networking, I went on to university and successfully obtained a 2:1 honours degree in Networking and Computer Support. Following this I served my time working in Dell as a technical support representative, taking advantage of the free training on offer I gained many industry certifications, as a result was able to work my way from the desktop department to the Enterprise department. Eventually I got bored of taking calls about broken hardware and moved to my current company, William Grant Distillers where I initially joined as a Service Desk Analyst. After 2 years I became a Client Services Technical Analyst and began to focus much more on software/operational functions rather than being purely support oriented.

      I still have a much to learn, but I really enjoy the challenge of learning new skills, the purpose for me of writing this blog is to keep some kind of record of that things I've been working on. In the fast moving world of IT it can be very difficult to remember to update you CV with all the new skills you've learned, so this will help me what that. If along the way I manage to make a few posts that clarify a few issues for other people working on similar projects and perhaps make a few new friends that will also be a good thing.

      Tomorrow I will start adding my first "proper" post, but I hope you will welcome me into the Blogger community.


      Andrew