Neil's profileNeil's SpacePhotosBlogListsMore Tools Help

Blog


    07 November

    HUGE day today

    I have been playing with a few toys in the recent past with the monad beta and the Vista beta (thanks very much Microsoft), but the one I have been most interested in for the past year or so has been the SQL 2005 beta (Yukon). This product is HUGE with additions to Reporting, OLAP and ETL that really boost the BI capabilities of this suite. Just the changes to the RDBMS in the form of CRL intigration, XML functionality and the security components have made the learning curve pretty steep. My favourite new component is probably the DDL triggers. I have had someone "Accidently" drop a table (stupid consultant) in production that this would have solved. I have to move along quickly now or I will go back to that last statement and get really bitter.
     
    ANYWAY, during the past couple of weeks SQL 2005 has moved from beta ware to a full product with the product being RTM (released to manufacturing) Oct 27th. I attended a seminar at MS in Mississauga, ON last Tuesday and today is the official release of SQL SERVER 2005!!!!!!! COOL!!!!
     
    So I am a little excited this week. But this isn't just the SQL launch, they are also officially releasing Visual Studio 2005 and BizTalk 2006 so its a big day for DBAs, Developers, integrator and BI specialists. Now all I have to do is learn the rest of the product. Shouldn't take more than a year or two...
    21 September

    Vista

    So I have finally gotten the opprotunity to install the beta of Windows Vista. I had one student who was unable to attend my class this week and that left me with a spare machine to play with over lunches and what not. Everyone in class wanted to have a look and I thought it would be a good idea to have the system around for teh rest of the week to kick teh tires.
     
    I am using the latest build (5219) and I have already learned a few lessons. Item one, Deamon Tools wont function so well as a virtual DVD for the install. Sure it installed the base Vista components but after the install, Vista would like to run a set of tools that will enable some of the older drivers available in XP...off of the DVD. Unfortunately, Deamon Tools is no longer available (unable to start Virtual SCSI interface) so I had to go digging for a real DVD and burn an image of the ISO file before I could get more than the 4 colours that were offered with the base video driver.
     
    Looks cool, IE7 is different (has an RSS reader built in) and the graphics are nice. It is a bit slow. Seems 1GB of RAM and a P4 2.4Ghz might not be peppy enough.
     
    I will keep you posted about what I think. (yes I am making entries to find out how the RSS reader in IE7 will pick it up)
    25 July

    I did not know that

    I have been hanging out in the SQL newsgroups a bit lately. Perhaps my brain will enlarge
     
    Anyway, today someone asked about converting character infromation into a date format. "No problem", I thought, "he can use the CONVERT function to do that". I read on a bit further and realised that his request was a little different. He had data in the format of YYYYWWD where the YYYY is the year, the WW is the week of the year and D is the day of the week. This would mean that 2005153 would equate to April 11, 2005 (3rd day of the 15th week of 2005). The problem is that I didn't see anything in BOL that would convert from that to a date format. hmmmm, dilema.
     
    Well, this peaked my curiousity and the poster even went so far as to say "Oracle can do it -- they have a  to_date function" WELL! If Oracle can do it, SQL should be able to do it. I'm not going to take this "your dad can beat up my dad" thing laying down! Neil cracks out the trusty Google, Books online and anything else around the desk - I'M ON A MISSION!!!! nothin'...I got nothin'...well, I got a little something but nothing exact. I did find this which got me started on building a function that would do what the poster had requested. Here is the function:
     
    create function fn_convdate (@yyyywwd char(7))
    returns datetime
    as
    begin
     
    DECLARE @week int, @year int, @day int,
    @wiy as datetime, @fdt as datetime
     
    select @year = SUBSTRING(@yyyywwd, 1, 4)
    SELECT @week = SUBSTRING(@yyyywwd, 5, 2)
    select @day = SUBSTRING(@yyyywwd, 7,1)
     
    select @wiy = dateadd (ww,@week-1,
    CONVERT(datetime,'01/01/'+CONVERT(char(4),@Year)))
    select @fdt = dateadd(dd,@day-1,@wiy)
    return (@fdt)
    end
     
    If you can use it great, if not at least I have a copy for myself down the road
     
    and kudos to Brett K for the leg up
    27 June

    Someone owes someone money

    So I finally got a chance to install VMWare 5. As an MCT we got a copy so we could evaluate and *ah-hem* compare it against MS VPC (preferably in VMWares favour and even better in front of a classroom full of eager purchasing students). Well I'm installing it an I notice that they have some tabs on the top. WHAT!?!?! If you were at TechEd and spent some time in the Hands on Labs (one of the best parts of TE, IMHO) you will have noticed a special interface on the labs. It used Virtual Server but it was very good. It's just those Tabs in VMWare are lookin REAL familiar. COREY, BRAD, grab some lawyers. somebody owes you some cash...
     
    24 June

    Make SQL work

    A common task for a DBA is to refresh development databases with some or all of the information in production. This is so the Devlopers can wreak havoc on recent data and the DBAs can keep thier jobs. We usually do this here with a simple backup of the production database and a restore over the development db.  I do the backups of Production data because it's on-line which is saves me from the downtime involved in detach/attach (no downtime is a good thing for payroll). A small hiccup comes in the form of what happens to the user ID in the database when you are using mixed mode authentication. Quiet often you will open up SEM and find that there are user IDs but the corresponding login is blank. It can also happen when you do reattach a database. This is becuase the SID of the user ID is different on this box from the previous. Fotunately SQL has a stored proc that can help.

    sp_change_users_login will allow you to remap a User to a Login. Check out books online (use the sp3a version) for the full details, but watch out for the auto_fix which can also recreate logins - which may or may not be what you want.

     Fine. Many of you might already know this (the sp_change_users_login), but my dimela arose when I realized that for our financials to be refreshed there would be trouble. You see the app makes EXTENSIVE use of DTC and after I restored the 53 databases there would be the 600+ user IDs in each db to remap. Images of extreme Carpel Tunnel Syndrome flash through my mind. Sure there is some app out there that will do this for me, but HEY I should be able to find a way to do this! It's actually very easy, and being the extremely nice (and handsome) person that I am, I am going to share it with you (yes it's all in T-SQL).

    1. create a stored procedure in the master database:

      CREATE PROCEDURE [dbo].[sp__matchusernames] AS
      --attach users to matching logins
      declare @name as varchar (30)
      declare curUsers cursor --yes I used a Cursor, I'm willing to accept suggestions
      for select name from sysusers where issqluser = 1 and name not like 'guest' and name not like 'dbo' and name not like 'INFORMATION_SCHEMA' and not like 'system_function_schema'

      open curUsers

      fetch next from curUsers
      INTO @name

      WHILE @@FETCH_STATUS = 0
      BEGIN
         --PRINT  @name --use to just see names to be matched
      exec sp_change_users_login 'Update_One', @name, @name
      fetch next from curUsers
      INTO @name
      END

      CLOSE curUsers
      DEALLOCATE curUsers
      GO

      note that the guest, dbo and INFORMATION_SCHEMA ids are ignored from the list. also this assumes that the USER IDs are the same name as the Logins. final note, the sp name uses two underscores so that I can keep it separate from my other sp's (also show in the top of the list).
    2. You could run this against only the user databases, or one at a time aginst the individual databases, or (if your like me) be really lazy. I choose to use the undocumented but extremely well know Stored Proc sp_MSForEachDb.

      sp_MSForEachDb 'Use [?]; exec dbo.sp__matchusernames'

      This will check and update all of the user IDs in ALL of the databases. For the most part, this will return the wonderous message of:

      The number of orphaned users fixed by updating users was 0.

      for the databases that are ok, and a number greater than 0 for the ones that had users that need fixin'. If you do get errors, it's likely becuse the User ID can't find a match for the login ID of the same name.

    There you go, short sweet and to the point. Enjoy! (I can here you rifling thru google for more info on sp_MSForEachDb even as we speak <g>)

    NEW TOYS!!! (ExBPA 2.1)

    I love when someone else takes the time to create something that makes me llok smart to others (even though I'm not). This is absolutely the case with Misrosoft's BPA series. There are a couple of these (there is another for SQL as well), and today MS released version 2.1 of the Exchange BPA. "You had me at EHLO" has done a write up on it that you should take a look at. I collegue at another company informed me that this tool has been lots of fun for him as he has been able to point out the Exchange problems to the Exchange admin. Use it wisely kids, don't be getting you fellow IT people in trouble. Just tell tehm where to get the ExBPA.

    22 June

    things I gotta find time to do

    It seems like only yesterday that I got back from TechEd, but I haven't stopped moving since. I worked the weekend and have been putting in long hours piecing things together here in the office. I think they were saving things for me <grin>.

    There were quite a few things at TechEd that I saw that I just have to investigate further. One of them is Monad or MSH. This upcoming goodie will really change the way administrative scripting is done. Anton went to the session (I was next door) and raved about it over lunch. Jerry, Rolly and I were next door and could hear the response it was getting - that was a lot of Whopping it up! I popped over to Beta place last night (armed with my magical guest code - no I don't think I can give that to you) and signed up. Got the approval to go get the thing today so I will likely download it tonight and play a bit when I get a free moment (some time in the year 2010).

    Also nice was to get back from TechEd and find that VMWare will upgrade my MCT copy of workstation 4 to workstation 5 -- FREE! I have downloaded that, but again I haven't had the chance to even install it yet. The trades (eWeek) had great reviews for this, so I really want to take a peek. Microsofts Virtual PC is still MUCH cheaper and for the price tag of VMWare's workstation, you just can just about justify Virtual Server from MS. There are huge limitations with each product and while I wont advocate one over the other, I would strongly encourage anyone prepping for exams, developing software, running development servers parrallel to production servers...to go look at the virtualization possibilities today. This stuff ROCKS!!! </end commercial> If you did get to TechEd, you had the chance to see what can be done with VS in the HOLs. Corey and Brad did an amazing job on the labs and I hope that this finds its way into Microsoft Official Curriculum (MOC) and replaces the VPC labs we do now.

    Last on my list (for today), but the first (or maybe second) that I want to get my grubby mud-hooks into is the copy of SQL 2k5 that we snagged at TechEd. The June CTP was released for a public beta (don't know where YOU can get it - I have my copy) along witt the Readiness Kit and the upgrade analyzer. Away with you, go fetch! You really will enjoy what you find in it; I sure did.

    Now if I can just get over the physical/mental exhaustion from the past 3 weeks...

    (on the plus side I really do enjoy wearing the T-Shirt that MS gave us at TechEd last Friday to the office)

    23 May

    Avalon and Indigo pre-releases

    MS released pre-release versions of Avalon and Indigo today. This will allow the general public to test new features that will become available in Longhorn. Microsoft does give you fair warning though:

    Note: This is a Beta release . Therefore, do not install these builds on machines you depend on.

    No real suprise there. Can't wait to through it on the spare XP box I have for my VMs ;)

    if you're interested you might also want to have a peak at Karsten's article

    06 May

    Big day

    Wow! It seems that when things happen, they all happen at once. Microsoft has been busy boys and girls this week. Must be the fact that TechEd is coming and they will wnat to be showing off left, right and center. Today they have announced the public availability of the R2 beta (http://www.microsoft.com/windowsserver2003/R2/default.mspx) and I also recieved my e-mail statign that SQL SP4 is now out of beta and has gone live and they thanked me for my input (such as it was). SQL SP4 is available at:

     http://www.microsoft.com/sql/downloads/2000/sp4.asp

    So far the beta or SP4 was rock solid. I had no problems on my end. Hopefully this will be the case as we move it into production.

    19 April

    No SQL 2005 Beta 3?

    So Buck Woody (ok, sorry but that has got to be the best porn name ever) has mentioned that MS will not be releasing Beta 3 for SQL2k5:

    http://tinyurl.com/cwcv9

    18 April

    Look what Rod F. dug up!

    Over at Rod Fournier's great list of schtuff (http://www.msmvps.com/clustering/) he's managed to find some info on pricing and packages for SQL 2005. COOL!

    http://www.microsoft.com/sql/spotlight/images/expand_550x420.gif

    13 April

    Fun with SQL, AD and PS part 3

    In the final section of this trilogy of my personal documentation there is the issue of pushing the info back into AD. As I mentioned in the first article Julie asked me to find a quicky backup method so my scheduled job begins with an xpcmdshell to a batch file that runs the following:

    csvde.exe -f c:\export.txt -r "(objectCategory=user)"

    If you have never used CSVDE or LDIFDE you should dig out the documentation from the MS site (or through google) and have a peek. The major difference between the two is that CSVDE can only be used for adding user accounts, while LDIFDE can be used for adding and updating accounts. I can hear the question already. I've heard it in class. "Um, Neil? You've used CSVDE there. I thought that CSVDE couldn't be used for updates." True enough, but here we are exporting from Active Directory, not importing into. The plan is to create an LDIFDE file should the need arise at a later point. I have found that one of the easiest ways to create an LDIFDE file is to use the Mail Merge feature from word and have a source file in some other format to build the LDIFDE. CSV files work very nicely with Mail Merge. See the fit?

    Alright, the final component was to push it back to AD. So since I used that big honkin T-SQL script to pull everythign from AD, it should be a piece of cake to use an update script to put it back right? Wrong. unfortunately after several days of bashing my head against the proverbial wall, I admitted defeat and moved on to ADO create the import into AD. First let me emphasise that I am not a true code jockey by nature, which should also explain a great deal about my code. I had avoided this up till this point as I have had limited access to coding with ADO and was anticipating a bit of a learning curve. Had I realised how easy and eligent the ADO enviornment was I would have started with that and likely saved myself considerable grief. To take the data from the SQL staging table and put it into AD required only the following script (as a vbscipt):

    ''
    '' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 3.0
    ''
    '' NAME: Update AD from SQL (adsql.vbs)
    ''
    '' AUTHOR:  Neil MacMurchy
    '' DATE  : 4/4/2005
    ''
    '' COMMENT: Takes data from SQL and updates Active Directory fields
    ''
    ''==========================================================================

    Const adOpenStatic = 3
    Const adLockOptimistic = 3
    Const adUseClient = 3
    Set objConnection = CreateObject("ADODB.Connection")
    Set objRecordset = CreateObject("ADODB.Recordset")
    objConnection.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=daDatabase;Data Source=daServer"
    objRecordset.CursorLocation = adUseClient
    objRecordset.Open "SELECT * FROM tblAD Where extensionAttribute9 not like N''%none%'' and extensionAttribute9 is not null and department is not null and title is not null" , objConnection, _
     adOpenStatic, adLockOptimistic

    ''========================================
    ''this section goes to the first record in recordset and updates each entry
    ''
    ''========================================
    objRecordSet.movefirst
    Do while Not objRecordSet.eof
    adsPath =objRecordSet("adspath")
    title = objRecordSet ("title")
    dept = objRecordSet("department")

    Set objUser = GetObject (adspath)
     
    objUser.Put "title", title
    objUser.Put "department", dept
    objUser.SetInfo
    objRecordSet.movenext
    loop
     
    set objUser = nothing
    set objRecordSet = nothing
    set objConnection = Nothing

    SO SIMPLE! I would strongly encourage anyone considering creating convoluted T-SQL script that will need to intereact with other system look at ADO. I will certainly be spending more time with it in the future. As for using in a scheduled SQL job it's simply choosing "ActiveX Script" from the type drop down and away you go.  

    Well if nothing else it was indeed a learning experience.

    12 April

    Exchange 2k/2k3 Hotfix

    http://www.microsoft.com/technet/security/bulletin/ms05-021.mspx

    "This update resolves a newly-discovered, privately-reported vulnerability in Microsoft Exchange Server that could allow an attacker to run arbitrary code on the system"

    08 April

    Fun with SQL, AD and PS part 2

    ok, last time we looked at how I pulled in a list of AD users into a SQL staging table. The big question at this point is likely "who cares". Well, I wanted to document this. The original purpose of a web log was to track administrator actions. So, I thought I would put down these thoughts for my own future reference. If you've stumbled across this and have found it useful, cool.

    So, to update the staging table with the HR data in PeopleSoft data I had to deal with one of ERPs dirty little secrets. Most ERP systems provide little more than a passing glace at DRI built into the database itself and rely on the application/business process layers to handle integrity. This leads to the problem of attempting to pull valid information from the underlying tables. The only information I needed was the department and titles. This can be found in the PS_DEPT_TBL, PS_JOBS and PS_JOBCODE_TBL. The effective dating makes it almost impossible to get the RIGHT data. Mercifully, there is also a table that is dynamically created pulling the information from PS_JOBS and PS_JOBCODE_TBL and a few others that then combine into the PS_EMPLOYEES table. This combined with a bit of a kludge from PS_DEPT_TBL got me what I needed. I created a view that would retrieve only the current departments from PS_DEPT_TBL:

    create view curdept_vw
    as
    SELECT * FROM HR8PRD..PS_DEPT_TBL A

    WHERE A.EFFDT =   (SELECT MAX(A1.EFFDT) FROM HR8PRD..PS_DEPT_TBL A1
                       WHERE A1.SETID = A.SETID
                       AND A1.DEPTID = A.DEPTID
                     AND A1.EFFDT <= GETDATE())
          AND A.EFF_STATUS = 'A'

    This view will use the max effective date that is not future dated to find the current department ID. Since PS_EMPLOYEES has the DEPTID it was then a matter of mearly creating a view that would pull the Employee ID, title and department (in the listing as DESCR):

    CREATE VIEW dbo.empid_depts_vw
    AS
    SELECT     e.EMPLID, e.BUSINESS_TITLE, d.DESCR
    FROM         HR8PRD.dbo.PS_EMPLOYEES e INNER JOIN
                          dbo.curdept_vw d ON e.DEPTID = d.DEPTID

    Wonderful, the PS information is now at my disposal. now to clean up and update the infromation in the staging table in preporation for pushing it back into AD. We have used an extra AD attribute to house the employee ID for each of our users. This is the extensionAttribute9 AD attribute that will only exist if you have Exchange 2000 or 2003 in your forest. But we have had a few problems with the way the information that is in there. Some of the information in extensionAttribute9 came from ldifde imports that were built from  csv files. In PeopleSoft the EMPLID feild is fixed a 5 characters for us. If your EMPLID is only 3 digits (say you are employee 500) then the number is padded with leading zeros. When the infomration was in the csv file the leading zeros were dropped by Excel - you know, one of those things it just does. So the update script will need to handle fixing this as well.

    The other problems that I will have is the additional use of extensionAttribute9 and the collations of that column on the staging table when we pulled it from AD. Since we previously have used extensionAttribute9 for a script entry, the administrative accounts also have "none" in the field. to avoid overwriting this (I felt it would be good to have none for the "employee id" of the administrative accounts) the script must bypass these. Also when extracting the information from AD we HAD to use a collationtion of sql_latin1_general_cp1_ci_as which is incompatible with the PS collation of Latin1_General_BIN. One last piece, I wanted to avoid overwriting information in AD if there was nothing of value in PS. So this is what we have:

    /*fix the short EMPLIDs*/
    update tblAD
    Set extensionAttribute9 = ''00''+extensionAttribute9
    where LEN(extensionAttribute9)<4 and extensionAttribute9 not like ''%none%''

    update tblAD
    Set extensionAttribute9 = ''0''+extensionAttribute9
    where LEN(extensionAttribute9)<5 and extensionAttribute9 not like ''%none%''

    /*alter table so collation in AD matches PS*/
    Alter Table tblAD Alter Column extensionAttribute9
     Varchar(11) COLLATE Latin1_General_BIN  NULL
    go

    /*update the titles in the source AD table using PS info*/
    update tblAD
    set tblAD.title = e.BUSINESS_TITLE from empid_depts_vw e
    where tblAD.extensionAttribute9 = e.EMPLID
    and e.BUSINESS_TITLE is not null

    /*update the departments in the source AD table using PS info*/
    update tblAD
    set tblAD.department = e.DESCR from empid_depts_vw e
    where tblAD.extensionAttribute9 = e.EMPLID
    and e.DESCR is not null

    Next time we'll go over how to get the information back into AD. It wasn;t as simple as I would have liked

    06 April

    Fun with SQL, AD and PS Part 1

    well for a few weeks I have had some fun with a project here to update Active Directory using some of the information currently held in our PeopleSoft HR databases. Sounds straight forward. famous last words...

    I broke down the mini project into about 4 parts. The first part required that the user account information be pulled into a staging table in SQL. A standard update script would then extract from PeopleSoft the required fields into into the staging table and export that back to AD. the forth step was recommended by Julie and would actually be a quick ldifde/csvde export prior to all of this fun just to be safe should something not go perfectly. WHAT? Don't you trust me? 

    Ok, so first we need to find a mechanism to pull the AD Stuff into the staging table. I created a database called NBM1 that would house the staging table. While this (pulling the information from AD) sounds simple enought to do with T-SQL there are issues. First off you need to have sufficient permissions on both the SQL server and AD to pull this info adn you must set up new linked server that uses Active Directory. http://www.microsoft.com/technet/prodtechnol/sql/2000/books/c01ppcsq.mspx#EBAA gives a brief explaination of how to do this but you really need to be aware that the security must be set up properly for the linked server. Make sure that on the security tab you have either setup up local logins that have Admin level permissions in AD or the "for logins not listed above, connections will:" setting is set to "be made using this security context" and use an account that will have AD admin permissions.

    Fine, done, now I try to use the view example at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/distributed_query.asp as a tempplate to see if I have issues. I do. In smaller organisations this view will work flawlessly. Unfortunately, when you have more than 1000 users in AD, the default settings will return only 1000 records. After digging thru google, I stumbled across the blog of Brendan Tompkins were he was attempting to resolve just this item in Dec of 2003. Along with Hermann Croucamp they provided a template for what would become the stored procedure for my evil master plan. I wanted to keep as much of this T-SQL but as Hermann mentions at the bottom of the article it might be best to go thru ADO and use objCommand.Properties(@Page Size@) = 1000 instead.

    so here is the procedure

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_adupdate]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[sp_adupdate]
    GO

    SET QUOTED_IDENTIFIER OFF
    GO
    SET ANSI_NULLS ON
    GO
    SET ANSI_WARNINGS ON
    GO

    CREATE PROCEDURE [dbo].[sp_adupdate] AS
    declare
    @vchChars varchar(100)
    , @vchTest varchar(10)
    , @intLength tinyint
    , @intStep tinyint
    , @intSubStep tinyint
    , @intCompPos tinyint
    , @intRowCount smallint
    , @intCycleCount smallint
    , @intMaxCompare smallint
    , @bitStepNext bit
    , @bitSubStepNext bit
    , @nvchSQL nvarchar(4000)
    , @nvarOU nvarchar(200)
    , @nvchDC nvarchar(100)
    , @nvchCN varchar(256)

     

    set @nvchDC = 'DC=ourdomain,DC=com' --change this for your domain 
    --set @nvarOU =  'OU= ''' --set equal to '' if not needed
    set @vchChars = '-_`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    set @intMaxCompare = 3 --this will set the maximum chars to compare for the last char in @vchChars
    --if not set, the script will go into a never ending loop (only if last char has more than a 1000 which is not likely for Z)

    set nocount on

    if exists (select * from nbm1.dbo.sysobjects where id = object_id('nbm1.dbo.tblAD'))
    drop table tblAD

    if exists (select * from tempdb.dbo.sysobjects where id = object_id('tempdb.dbo.#ldap'))
    drop table #ldap

    create table [dbo].[#ldap] (
    [row_id] [int] IDENTITY (1, 1) NOT NULL ,
    [cn] [nvarchar] (50) collate sql_latin1_general_cp1_ci_as null ,
    [sn] [nvarchar] (50)  collate sql_latin1_general_cp1_ci_as null ,
    [givenName] [nvarchar] (50)  collate sql_latin1_general_cp1_ci_as null ,
    [telephoneNumber] [nvarchar] (25)  collate sql_latin1_general_cp1_ci_as null ,
    [title] [nvarchar] (50)  collate sql_latin1_general_cp1_ci_as null ,
    [extensionAttribute9] [nvarchar] (5)  collate sql_latin1_general_cp1_ci_as null ,
    [department] [nvarchar] (50)  collate sql_latin1_general_cp1_ci_as null ,
    [adspath] [nvarchar] (256) collate sql_latin1_general_cp1_ci_as null
    ) on [primary]

     

    if len(@vchChars) > 0
    begin
    set @intStep = 1
    while @intStep <= len(@vchChars)
    begin
    set @bitStepNext = 0
    set @intCycleCount = 0
    set @intSubStep = 2 --start comparison on second character
    set @intCompPos = 1
    set @intRowCount = 0
    set @bitSubStepNext = 0

    while @bitStepNext = 0
    begin
    if @intCycleCount = 0
    set @vchTest = substring(@vchChars, @intStep, 1)
    else
    begin
    select top 1 @nvchCN = cn from #ldap order by row_id desc
    if @bitSubStepNext = 0
    set @intCompPos = charindex(substring(@nvchCN, @intSubStep, 1), @vchChars, 1)

    set @vchTest = substring(@vchTest, 1, (@intSubStep - 1)) + substring(@vchChars, @intCompPos, 1)


    set @bitSubStepNext = 0
    end

    set @nvchSQL = 'insert into #ldap ' +
    'select cn, sn, givenName, telephoneNumber, title, extensionAttribute9, department, adspath ' +
    'from openquery(ADSI,''<LDAP://' /*+ @nvarOU + ','*/ + @nvchDC + '>;(&(objectCategory=Person)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(cn=' + @vchTest + '*));cn, givenName, sn, telephoneNumber, title, extensionAttribute9, department, adspath;subtree'') q '+
    'where not exists (select adspath from #ldap ld where ld.adspath = q.adspath)' +
    'order by cn'

    exec sp_executesql @nvchSQL

    set @intRowCount = @@rowcount
    --print @vchTest + ' : ' + convert(varchar, @intRowCount) + ' : ' + convert(varchar, @intCompPos) --keep print after the @@rowcount statement or it will reset @@rowcount

    if (@intRowCount < 1000 and @intCycleCount = 0) or ((@intCompPos = len(@vchChars) and @intCycleCount > 0 and (@intSubStep = @intMaxCompare or (@intSubStep = 2 and @intRowCount = 0))))
    set @bitStepNext = 1
    else
    begin
    set @intCycleCount = @intCycleCount + 1
    if @intRowCount < 1000
    begin
    if (@intCompPos = len(@vchChars))
    begin
    set @intSubStep = @intSubStep - 1
    if @intSubStep < 2
    set @intSubStep = 2
    end
    else
    begin
    set @bitSubStepNext = 1
    set @intCompPos = @intCompPos + 1
    end
    end
    else
    begin
    set @intCompPos = 1
    set @intSubStep = @intSubStep + 1
    if (@intCompPos = len(@vchChars) and @intSubStep > 3)
    begin
    set @intSubStep = @intSubStep - 1
    if @intSubStep < 2
    set @intSubStep = 2
    end
    end
    end
    end
    set @intStep = @intStep + 1
    end

    set nocount off

    select * into tblAD from #ldap order by cn
    end
    else
    print 'No characters specified'

    GO
    SET QUOTED_IDENTIFIER OFF
    GO
    SET ANSI_NULLS ON
    GO

    Next I will talk about the view I needed for the pull from PeopleSoft...

    29 March

    This is new

    I am a big fan of blogging. DUH! when I first got involved with reading syndicated blogs and RSS feeds, I was an avid consumer and found it a great tool for researching news and new technology. It still consumes a fair portion of my time reading and learning what's new. Some of the blogs aer indispensible. Like the MS Exchange blog hosted by Microsoft called "You had me at EHLO". I saw a post recently asked if there were other Microsoft hosted blogs geared to Active Directory. While there are several bloggers discussing off and on AD, I could not point to a single location for this poster to look.

    Now I do.

    Unfortunately this has brought both good and bad news for me. The new location of MS hosted blogs at http://blogs.technet.com/ gives a single source for someone to search and access the vast wealth of the knowledge of MS employees. One the down side, moving the blogs to this new location seems to have force fed my RSS reader a ton of activity.

    Well if you will excuse me, I must read a lot of feeds

    23 March

    Virtual machines in PowerPoint

    ok, over at Virtual PC Guy's blog, Ben has noted that you can control a Microsoft Virtual PC (or Virtual Server) from within a PowerPoint persentation. As a trainer this is huge as it would allow me to set up a presentation and without ever leaving the slideshow I could be demoing whatever tech was in the VPC. Would also be really good for sales demo.

    *shudder* Sales people with the tech expertise to install a VPC and setup a Win2k3/Exchange2k3 (or whatever) demo and run it from powerpoint? ok, that might be a stretch.

    18 March

    News Aggregators Part 3 (the finale)

    Ok, time to finish this off. Where to get feeds and what you will see in the readers. As I mentioned in the first article you can find News feeds all over the internet if you look for pages that display the RSS, ATOM or XML logos. At the bottom of this page you will find an orange RSS logo. If you click on it you will get an xml output, but the link can be used in the readers. In RSS Reader for example, click the add button and paste the link in and follow the prompts. In SharpReader you can just past the link into SharpReader’s address bar and click on the subscribe button. Once the link has been subscribed the reader will “go fetch” every hour (by default those this behaviour can be modified in the tools – options – feed (properties) of the readers. Yes they are both in almost identically named locations). If you want to find a feed on a specific topic there is always Google. Google bought out Blogger a couple of years back and they really do have a nice blog product. There are other tools for finding feeds such as blogfinder.com and blogdigger.com. But beware, too many feeds can overload you with information.

     

    Every hour the reader will go out and check for updates. The good news is it just sit in you system tray (notification area, whatever!) until there is an update to one of the feeds that it needs to tell you about. This is were there is IMHO a difference between SharpReader and RSS Reader. I prefer RSS Reader because Sharpreader has a series of popups that inform you of updates to each feed. They pop up and disappear fairly quickly – too quickly for a slowpoke like me. RSS reader shows one popup for all feeds that have updates and will display this for 60 seconds. Now that’s not enough time if there are a lot of news articles that I want to see the titles of, so RSS Reader also has a “push pin” that hold the window open for you to have a peek at the titles (yes in both cases it’s just the titles of the articles). Check out the images at the bottom of the page for a comparison. The blue one is SharpReader and the yellow is RSS Reader.

     

    In either case once you click on the title of the article you want to read, the full application will open and you will have a Windows Explorer like screen that displays a tree view of the feeds on the left and on the right the screen is split horizontally with the titles of all articles (for that feed) on the top and (if you click a title) the article itself on the bottom. Note that if you click on a link within the article that they act as a mini-browser. I find this a real pain and usually right click the links to open them in a new window.

     

    Well, that’s it. Go play around with the readers and let me know what you think. There’s tons of useful info out there. Now you have it at your finger tips. But be careful – we wouldn’t want to learn anything.