March 2007 - Posts

Softgrid Sessions at MMS

My co-worker Sean McHugh and I are back for our second year at MMS, and already we can already tell this is going to be an awesome week! We're really looking forward to some of the sessions and labs we have scheduled, especially the Softgrid stuff. If you're still mulling about which sessions to take, I really encourage you to check out some of the Softgrid sessions. Once you wrap your brain around what it does along with some of the other functions of MDOP, its easy to get excited about how this will revolutionize application deployment! We are looking at deploying this at our company next month and it will cut our SMS package development time down from days (or sometimes weeks) to just several minutes. It also does other cool tricks such as updating and tracking your apps.

 If you're not able to get into any of the labs, at least check out the Softgrid virtual lab that Anthony Clendenen posted about earlier in his blog here.

Posted by bleary with 1 comment(s)

Download: Creating SMS Web Reports from SMS Queries

I had a couple different people e-mail me and say that they couldn't see the images for my "Creating SMS Web Reports from SMS Queries" blog posts. I thought that it might just be due to the page taking too long to load as I could see the images just fine, but it turns out they were right - the images weren't published properly. I fixed the problem, but if anyone still has trouble viewing the posts and wants to download an offline copy, I have it attached to this posting.

Posted by bleary with 1 comment(s)

Creating SMS Web Reports from SMS Queries - Part I

From SMS Query to SQL Query

In the past, there have been some articles written on myITforum.com and also some forum posts describing how to use the smsprov.log file to convert SMS queries to SQL queries. This is a fairly simple procedure, but if you try to take it a step further to create a web report using this method, the query causes a 'SELECT permission denied' error when the report is run. In this series of articles, I am going to explain how to use SQL views from the SMS database in a SQL query to avoid this error, speed up the query process as well, and teach you some basic Transact-SQL.

Converting from an SMS Query to a SQL Query
The first thing we will look at is how to take an SMS query and convert it to a SQL query which will later become our web report. We'll start with a fairly simple SMS query to return the SMS Site Code, System Name, Last User Logon Name, and Add/Remove Program Display Name for any systems that have Internet Explorer 7 installed. Here's the WQL language so you can just paste it into an SMS query:

select SMS_R_System.SMSAssignedSites, SMS_R_System.Name, SMS_R_System.LastLogonUserName, SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId where SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName = "Windows Internet Explorer 7"

Run the query in SMS and view the results. Now open up the SMS SQL provider log file named smsprov.log which resides in the \SMS\Logs directory on the site server and scroll to the bottom of the log. You will see a line that starts with "Execute WQL=" followed by the SMS query that you pasted in. Immediately below that, there is a line that begins with "Execute SQL=" followed by the SQL query that the SMS SQL Provider converted from WQL. Highlight the SQL query from "select all" to the end and copy it. The SQL query looks like this:

select  all SMS_R_System.ItemKey,SMS_R_System.Name0,SMS_R_System.User_Name0,__System_ADD_REMOVE_PROGRAMS0.DisplayName00 from System_DISC AS SMS_R_System INNER JOIN Add_Remove_Programs_DATA AS __System_ADD_REMOVE_PROGRAMS0 ON __System_ADD_REMOVE_PROGRAMS0.MachineID = SMS_R_System.ItemKey   where __System_ADD_REMOVE_PROGRAMS0.DisplayName00 = "Windows Internet Explorer 7"

From a SQL Query to an SMS Web Report that doesn’t work
Now we’re going to create an SMS Web Report from this SQL query so you can see what the ‘SELECT permission denied’ error looks like. In the SMS Administrator’s Console, expand the Reporting node, and then right-click on Reports. From the pop-up menu, select New -> Report and title it, “All Systems with Microsoft Internet Explorer 7” and then click on the Edit SQL Statement button. Delete the default query text in the SQL Statement window, paste in our SQL query, and then click on OK. The report properties should look like this:

Query Analyzer0

Click on OK to save the report. To run the report, right-click on it in the SMS Administrator Console, and then from the pop-up menu select All Tasks -> Run -> YourSMSReportingServerName. When you run the report, you should see an error message like this: Web Report Error 1

So why is it that we can run this query in SMS which passes it to SQL flawlessly, yet when we take the same SQL query and dump it into a web report we get this error? The answer is that the SQL query references SQL tables, and the SMS SQL provider lets you access those tables through the SMS Administrator’s console. When you try to run the web report, the SQL provider is out of the picture, and in the context of permissions that you are running the web report under you don’t have permissions to the SQL tables – and that’s a good thing! You wouldn’t want your users who have access to your web reports to have direct rights to the data in your SQL tables.

The solution to this is to use SQL views in your web report, which your users will have access to and it will also speed up your querying process. In part 2 of this article, we will go though how to convert your SQL query to use SMS views.

Posted by bleary with 3 comment(s)

Creating SMS Web Reports from SMS Queries - Part II

Using Query Analyzer

In part one of this article series, we saw how to convert an SMS query to a SQL query, but when we tried to take the same SQL statement and make it a web report it returned a ‘permissions denied’ error. Part two will provide an overview on how to use Query Analyzer, what SQL tables are, and how to run a SQL query.

 

**DISCLAIMER: The exercises in this article discuss how to read data from a SQL database using SELECT statements. As long as you stay within the confines of what is being presented, you do not run any risk of damaging or altering your SQL data. Unless you are aware of what you are doing or are instructed by someone who knows SQL, you should never alter the data in your SMS database either directly or through INSERT or UPDATE statements. That being said, please don’t blame me if you crush your database by deviating from the exercises and venturing off on your own!

 

Editing the SQL Query using Query Analyzer
Go to the Microsoft SQL Server program group and open the SQL 2000 Query Analyzer which allows you to run SQL queries against your SMS database. I'm using the older version of SQL for this article since not everyone is using SQL 2005 so the SQL 2000 Query Analyzer is a better common ground. (If you’re using SQL 2005 then you would use the Query Editor instead of Query Analyzer.) Now type in your SQL server name where the SMS database resides and select either Windows or SQL Server authentication depending on which option you chose when you installed SMS. If you use SQL Server authentication you will need to provide a username and password for a SQL account that has access to the SMS database. After clicking on OK, you need to select your SMS database from the drop down menu on the toolbar at the top of the screen. If you don’t do this then you will get an error stating, “Invalid object name” when the query tries to run. Now cut and paste the SQL query that we pulled from the smsprov.log file in Part 1 of this article series into the Query Analyzer window. For convenience, here’s the SQL query:

select  all SMS_R_System.ItemKey,SMS_R_System.Name0,SMS_R_System.User_Name0,__System_ADD_REMOVE_PROGRAMS0.DisplayName00 from System_DISC AS SMS_R_System INNER JOIN Add_Remove_Programs_DATA AS __System_ADD_REMOVE_PROGRAMS0 ON __System_ADD_REMOVE_PROGRAMS0.MachineID = SMS_R_System.ItemKey   where __System_ADD_REMOVE_PROGRAMS0.DisplayName00 = "Windows Internet Explorer 7"

Your window should now look something like the screen shot below, but please note that I have removed my server name from the Query Analyzer window due to company policy. If you’re not seeing the object browser pane on the left side, then hit the F8 key to display it. For readability, I’ve added some line breaks into the query, which Query Analyzer will ignore when the query runs.

QueryAnalyzer1

What are SQL Tables?

Before we proceed in modifying this query, we need to understand what it is doing. One of the first things you will need to know if you don’t already is that SQL stores its data in tables. Let’s use the Object Browser window on the left side to look at some tables in the SMS database. Expand your SMS database name, and then expand User Tables. If you scroll down, you will see a list of all the tables in your SMS database.

QueryAnalyzer2

Now we’re going to choose a table and display the data that resides in it. Scroll down to the table named, “dbo.CD_ROM_DATA” and expand it, then expand Columns. This shows all the different CD ROM information that SMS collects on a client system during a Hardware Inventory cycle as defined in your sms_def.mof file.

QueryAnalyzer3

Next, we’ll look at the data that resides in this table. Right click on dbo.CD_ROM_DATA. From the pop-up menu that appears, choose “Script object to new window as” then “Select” which will open a new window in Query Analyzer with a SQL query to return all the rows in the table. To run the query, you can either choose Execute from the Query menu in Query Analyzer or click on the green triangle in the toolbar. When the query runs, it will display all the CD ROM data that SMS has collected from your clients in the results pane on the bottom. If you scroll over to the right, you can see all the different columns.

QueryAnalyzer4

When you’re finished viewing the results, close the child window in SQL Analyzer by clicking on the gray X in the upper right hand corner to go back to our original SQL query for Internet Explorer 7. We will continue with this in Part 3 of this article, where we will look at the SQL query and decipher what each line in the query is doing.

Posted by bleary with no comments

Creating SMS Web Reports from SMS Queries - Part III

Deciphering the SQL Query

Part 2 of this series showed how to use the SQL 2000 Query Analyzer, what SQL tables are, and showed how to run a SQL query. In Part 3 we will look at each line of the SQL query and explain what it is doing. From where we left off in the previous article, you should be back to having Query Analyzer with the IE 7 SQL query pasted in the query window.

QueryAnalyzer1

Some Transact SQL Basics

So now let’s take a moment to examine the SQL query and understand what it is doing. You will notice that SQL has very similar syntax to the WQL queries in SMS that are automatically generated when you create an SMS query. Each query contains keywords that Query Analyzer recognizes and highlights in blue. There are numerous reserved keywords in SQL, but for the purpose of this article we are only examining a few as they are the most common ones that you will run into. The ones we will be learning are SELECT, FROM, AS, INNER JOIN, ON, and WHERE.

 

In order to explain these keywords, we will start with a basic overview of the entire SQL statement and then go back and explain each keyword in detail. This may seem confusing at first, but hang in there and it will make more sense in a minute. Let’s start with the entire SQL statement again; for readability, I will be highlighting the SQL keywords in blue:

 

SELECT ALL SMS_R_System.ItemKey, SMS_R_System.Name0, SMS_R_System.User_Name0, __System_ADD_REMOVE_PROGRAMS0.DisplayName00

FROM System_DISC AS SMS_R_System

INNER JOIN Add_Remove_Programs_DATA AS __System_ADD_REMOVE_PROGRAMS0 ON __System_ADD_REMOVE_PROGRAMS0.MachineID = SMS_R_System.ItemKey  

WHERE __System_ADD_REMOVE_PROGRAMS0.DisplayName00 = "Windows Internet Explorer 7"

 

 

Now we’ll go into each line in further detail. SELECT is the first SQL keyword we will look at as it is the first one listed in the query, along with its secondary keyword ALL. Here’s the first line of the SQL query:

 

SELECT  ALL SMS_R_System.ItemKey, SMS_R_System.Name0, SMS_R_System.User_Name0, __System_ADD_REMOVE_PROGRAMS0.DisplayName00

 

The SELECT ALL keywords are followed by references in the form of Table Name or Alias.Column Name, each of which is separated by a comma. The ALL keyword is self-explanatory, but I want to point out that you can also use SELECT * to return the same results.

 

In our query, SMS_R_System is an alias for the table name System_DISC which is defined in the next SQL statement using the FROM and AS keywords in the next line. Additionally, we are displaying the DisplayName00 column from a table aliased as __System_ADD_REMOVE_PROGRAMS0. This alias is defined in the INNER JOIN statement which we will explain shortly. For now, we’ll look at the FROM statement next and then tie these two lines together. The FROM line is as follows:

 

FROM System_DISC AS SMS_R_System

 

This one’s easy; we’re selecting our columns from a table named System_DISC but from now on we are referring to it using the alias SMS_R_System. Let’s take a look at what we have so far in terms of the aliases, the red arrows show where each alias is used in the SELECT statement:

QueryAnalyzer5

Sorry about the mess; this obviously isn’t an art class, but hopefully you get the idea. I really need to stop using Microsoft Crayon and learn how to use Microsoft Paint instead!

 

Next we will look at INNER JOIN. There are several different types of joins in SQL, but for simplicity we will keep it limited to just this one. Basically, what an INNER JOIN does is to join two or more tables or views and display data from both of them. The ON keyword specifies which two columns that the join is linked on. Let’s examine what our INNER JOIN statement is doing in our query:

 

INNER JOIN Add_Remove_Programs_DATA AS __System_ADD_REMOVE_PROGRAMS0 ON __System_ADD_REMOVE_PROGRAMS0.MachineID = SMS_R_System.ItemKey

 

First we are taking the table named Add_Remove_Programs_DATA and aliasing it as __System_ADD_REMOVE_PROGRAMS0. The ON keyword is then linking the MachineID column from the table aliased as __System_ADD_REMOVE_PROGRAMS0 to the ItemKey column in the table aliased as SMS_R_System.

 

The last line with the WHERE keyword simply states that the only rows in the database that should be returned are the ones in the __System_ADD_REMOVE_PROGRAMS0 table where the data in the DisplayName00 column is equal to Windows Internet Explorer 7. This line looks like this:

 

WHERE __System_ADD_REMOVE_PROGRAMS0.DisplayName00 = “Windows Internet Explorer 7”

 

In summary, what our SQL query is saying is to display the columns named ItemKey, Name0, and UserName0 from a table called System_DISC which is aliased as SMS_R_System. We are also displaying another column named DisplayName00 from a table aliased as __System_ADD_REMOVE_PROGRAMS0, and this table is joined to the other table. This query will only return the rows where the __System_ADD_REMOVE_PROGRAMS0 table has data in the DisplayName00 column that is equal to Windows Internet Explorer 7.

 

So hopefully you now have at least a basic knowledge of what the SQL statement is doing, and you’re ready to start learning about SQL views which we will cover in Part 4. But before I close this article out, I have one more helpful tip: If you ever run across another keyword or want to look up more information on one of the ones that we’ve covered, Query Analyzer has context-sensitive help so you can highlight a particular keyword in a query then hit SHIFT+F1 to display help on that particular keyword. SQL Books Online has to be installed in order for this to work properly, which can be done by re-running the setup utility.

Posted by bleary with no comments

Creating SMS Web Reports from SMS Queries - Part IV

SQL Views 

In Part 3, we dismantled our SQL query and explained what it is doing and the logic behind it. In this article, we will be covering SQL views.

 

What are SQL Views?

SQL Views are predefined SQL queries that are run against one or more tables to present data to the user without actually giving them direct access to the SQL database. Views are kind of like a sneeze guard at a buffet line. Just as that quarter-inch piece of plastic protects the food from people’s forcefully expelled germs, SQL views prevent your users from contaminating your SMS database.

 

To use a view in a SQL query, you would treat it just as if it was a SQL table name. SMS automatically creates SQL views for the tables that are in the SMS database, so you should always be able to find the view you need to access any of the tables. Let’s open up Query Analyzer and look at a SQL view by expanding Views in the Object Browser. Scroll down to dbo.v_R_System, expand it, and then expand Columns. Your Object Browser should now look like this:

 QueryAnalyzer6

You may have noticed that after dbo., most views start with a letter ‘v’ followed by an underscore, which makes it easier to denote them as views. Now we will examine the SQL statement that defines the view. Right-click on dbo.v_R_System and select Edit from the menu. The SQL query for the view will open in a new Query Analyzer window, and that query looks like this:

 

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS OFF

GO

 

ALTER  VIEW dbo.v_R_System AS SELECT ItemKey As 'ResourceID', DiscArchKey As 'ResourceType',Active0,AD_Site_Name0,Client0,Client_Type0,Client_Version0,CPUType0,Creation_Date0,Decommissioned0,Hardware_ID0,User_Domain0,User_Name0,Name0,Netbios_Name0,Obsolete0,Operating_System_Name_and0,Previous_SMS_UUID0,Resource_Domain_OR_Workgr0,SMS_Unique_Identifier0,SMS_UUID_Change_Date0,Community_Name0 FROM System_DISC

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

 

There are a lot of new SQL keywords that you hadn’t seen before, but for the purpose of this article you don’t need to be concerned with what they do. For now, just look at the ALTER VIEW statement, where you can see that it is querying FROM System_DISC. We will look at that table next and compare its columns to the ones in the v_R_System view. Just to keep things easier to read, I will be leaving the dbo. off of the beginning of the view names throughout the rest of these articles. Now, close the child window and select to not save any changes.

 

Next, scroll up to User Tables, and then expand SystemDisc and Columns. You will see that most of the same columns exist in both the table and its related view. Here’s a look at both of them side by side so you can see the similarities. Query Analyzer doesn’t list them in alphabetical order, but you can see how the v_R_System view is comprised of most of the columns in the System_DISC table.

QueryAnalyzer8

In most cases, you will be able to figure out which view in your SMS database corresponds to which table just by browsing through the list of names as they are named similarly. Here are a few examples:

 

Table Name

View Name

System_DISC

v_R_System

ADD_REMOVE_PROGRAMS_DATA

v_GS_ADD_REMOVE_PROGRAMS

CD_ROM_DATA

v_GS_CDROM

OPERATING_SYSTEM_DATA

v_GS_OPERATING_SYSTEM

System_IP_Subnets_ARR

v_RA_System_IPSubnets

SoftwareFile

v_SoftwareFile

 

As you can see, it’s pretty straightforward. The table names usually end with _DATA and the aliases usually start with v_GS_, which is information that is gathered during a Hardware Inventory cycle. One thing that you do need to know is that the views that start with v_HS_ are referencing tables containing SMS history data. So unless you are writing an SMS Web Report to use historical information you will generally want to avoid using the v_HS views.

At this point, you should have enough of an idea of what the SQL statement is doing and how views are used, so we can now move on to Part 5 where we will start converting our SQL query to use SQL views.

Posted by bleary with no comments

Creating SMS Web Reports from SMS Queries - Part V

Modifying the report to use views

 

In Part 4, we defined what SQL views are and compared them with the tables. Now that you have all this SQL knowledge in that big brain of yours, we can finally start converting our SQL query to use SQL views instead of tables.

 

Switching to Views

We will start with our original SQL query which you should still have pasted in Query Analyzer. Make sure that your SMS database is selected in the database drop-down field on the toolbar before we proceed so that Query Analyzer knows that the queries you are running are against your SMS database. Here’s the original query again:

 

select  all SMS_R_System.ItemKey,SMS_R_System.Name0,SMS_R_System.User_Name0,__System_ADD_REMOVE_PROGRAMS0.DisplayName00 from System_DISC AS SMS_R_System INNER JOIN Add_Remove_Programs_DATA AS __System_ADD_REMOVE_PROGRAMS0 ON __System_ADD_REMOVE_PROGRAMS0.MachineID = SMS_R_System.ItemKey   where __System_ADD_REMOVE_PROGRAMS0.DisplayName00 = "Windows Internet Explorer 7"

 

Replace double quotes with single quotes

The first thing we’re going to do is to run the query and see what it returns. Go to the Query menu and select Execute, or hit the F5 key. The results pane will appear with the following error:

 

Server: Msg 207, Level 16, State 3, Line 1

Invalid column name 'Windows Internet Explorer 7'.

 

The problem is that SQL is expecting single quotes around the text string, ‘Windows Internet Explorer 7’ instead of double quotes. In order to use double quotes, you could use the SET QUOTED_IDENTIFIER keyword, but instead of messing around with that we’ll go ahead and give SQL what its expecting, which are single quotes.

 

This isn’t rocket science; it’s the same thing you’ve done in Microsoft Word or Excel or a bajillion other apps. Go to the Edit menu and select Replace. Enter a double quote in the Find field and a single quote in the Replace with field, and then click on the Replace All button. If you don’t feel like doing a Find/Replace, you can always just directly make the edit to the query.

QueryAnalyzer9

You’ll notice that as soon as you hit that button, ‘Windows Internet Explorer 7’ will turn red in the query window. That means that Query Analyzer now recognizes that as a text string because of the single quotes. Your Query Analyzer window should now look like this:

QueryAnalyzer10

Now that we made a change, let’s see what happens when you run the query:

QueryAnalyzer13

OK, so we’re getting some results now, but if you tried to put this query into a web report you would still get an ‘Access denied’ error as we still need to convert it to use SQL views. This is because of the permissions context that we are running under in Query Analyzer, which has more rights than when you run a web report. Notice also that the first column is displaying ItemKey instead of the SMS Site code so we will eventually need to fix that as well, but first we will take care of the views.

 

Replacing the table name System_DISC

Let’s start swapping table names for views by looking at the FROMAS line in the query, which currently looks like this:

 

FROM System_DISC AS SMS_R_System

 

We discussed this line back in Part 3 of this article series, where it was explained that this line is selecting our columns from a table named System_DISC and aliasing it as SMS_R_System. What we need to do at this point is to replace System_DISC with its corresponding view name, v_R_System. After performing the replace, the line should look like this:

 

FROM v_R_System AS SMS_R_System

 

So now we are telling Query Analyzer to select columns from the view named v_R_System and alias it as SMS_R_System.

 

Replace SMS_R_System with v_R_System

The next thing we’re going to do is to replace the alias name SMS_R_System. As before, so again: Edit -> Replace and populate the fields as shown below, then hit Replace All to replace the multiple instances of SMS_R_System in the query:

QueryAnalyzer11

Just to make sure we’re on the same page, Query Analyzer now looks like this:

QueryAnalyzer14

Since we’ve made this change, take a look at the FROMAS line:

 

FROM v_R_System AS v_R_System

 

Who’s writing this query? Someone from the Department Of Redundancy Department? What it is now saying is to select columns from the view named v_R_System and alias it as v_R_System. The whole purpose of using an alias is to give a long table or view name a shorter or friendlier way to reference the name. Since we are now just aliasing the view for what its name is anyway, we are going to remove it. Using an alias is optional, so this won’t affect the functionality of the query. Delete “AS v_R_System” from the FROM line so that it now reads as follows:

 

FROM v_R_System

 

We are now ready to move on to the next table/view name swaps that we need to do for Add_Remove_Programs.

 

Adding the Views for Add_Remove_Programs

This is a lot like what we just did for v_R_System. In the INNER JOIN line, replace the table name Add_Remove_Programs_DATA with its corresponding view name v_GS_ADD_REMOVE_PROGRAMS. Next, replace the alias name __System_ADD_REMOVE_PROGRAMS0 (note that that is a double underscore before System) with the view name v_GS_ADD_REMOVE_PROGRAMS, and you‘ll end up with this:

QueryAnalyzer15

Once again, we have a self-referencing alias in the INNER JOIN line:

 

INNER JOIN v_GS_ADD_REMOVE_PROGRAMS AS v_GS_ADD_REMOVE_PROGRAMS

 

Delete the alias, and then it becomes this:

 

INNER JOIN v_GS_ADD_REMOVE_PROGRAMS

 

Hopefully at this point you’re not completely lost, but if you are then here is what the query text should look like:

select all v_R_System.ItemKey, v_R_System.Name0, v_R_System.User_Name0,

 v_GS_ADD_REMOVE_PROGRAMS.DisplayName00

 

from v_R_System

 

INNER JOIN v_GS_ADD_REMOVE_PROGRAMS

 ON v_GS_ADD_REMOVE_PROGRAMS.MachineID = v_R_System.ItemKey  

 

where v_GS_ADD_REMOVE_PROGRAMS.DisplayName00 = 'Windows Internet Explorer 7'

 

Let’s see how we’re faring so far; go ahead and run the query and see what it does.

QueryAnalyzer16

Did you get a bunch of column name errors like I got? Excellent! Everything is working according to my plan! In Part 6 of this series, we will examine what caused these errors and how to clean them up.

Posted by bleary with no comments

Creating SMS Web Reports from SMS Queries - Part VI

Selecting the Proper Column Names From the Views

 

In Part 5, we replaced the table names with view names, and tidied up the query by removing the aliases. When we ran the query, there were several errors regarding invalid column names:

 

Server: Msg 207, Level 16, State 3, Line 1

Invalid column name 'MachineID'.

Server: Msg 207, Level 16, State 1, Line 1

Invalid column name 'ItemKey'.

Server: Msg 207, Level 16, State 1, Line 1

Invalid column name 'ItemKey'.

Server: Msg 207, Level 16, State 1, Line 1

Invalid column name 'DisplayName00'.

Server: Msg 207, Level 16, State 1, Line 1

Invalid column name 'DisplayName00'.

 

The reason that we are getting these errors is because the columns names in the views are different than those in the tables. Let’s take a look at the columns within the views and you’ll get a better idea.

 

Fixing the Error for MachineID

The first error in our list was for MachineID from the INNER JOIN line so we’ll check that one out first. In Query Analyzer, expand your SMS database name in the Object Browser on the left side, and then expand Views. Next, expand v_GS_ADD_REMOVE_PROGRAMS, and then expand its columns node. Notice that MachineID is not one of the listed columns, so when the query tried to reference v_GS_ADD_REMOVE_PROGRAMS.MachineID it was unable to find the MachineID column in that view.

QueryAnalyzer17

So here’s how to fix it. Right-click on v_GS_ADD_REMOVE_PROGRAMS and select Edit to display the query that created the view. The following query will appear in the query pane:

 

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS OFF

GO

ALTER  VIEW dbo.v_GS_ADD_REMOVE_PROGRAMS AS SELECT MachineID As 'ResourceID', InstanceKey As 'GroupID', RevisionID, AgentID, TimeKey As 'TimeStamp',DisplayName00 As 'DisplayName0',InstallDate00 As 'InstallDate0',ProdID00 As 'ProdID0',Publisher00 As 'Publisher0',Version00 As 'Version0' FROM Add_Remove_Programs_DATA

GO

SET QUOTED_IDENTIFIER OFF

GO

SET ANSI_NULLS ON

GO

 

The part I want to draw your attention to is the part I highlighted in the query, SELECT MachineID As 'ResourceID'. As you may recall from Part 4 of this article series, views are created by querying tables with a SQL statement and selecting the table columns that are used in the view. What’s happening here is that the view’s SQL query is selecting the MachineID column from the Add_Remove_Programs_DATA table and aliasing it as ResourceID in the view. If you look back over at the columns listed for the view, you will see ResourceID as one of the column names. So in order to get our query to work, we will have to replace MachineID with ResourceID since that is the column that is in the view. Close the child window by clicking on the gray X in the top right-hand corner of Query Analyzer, choose not to save the query, and you will be back at the original query. Look at the INNER JOIN line and find the column name, MachineID. I have it highlighted below:

 

INNER JOIN v_GS_ADD_REMOVE_PROGRAMS

 ON v_GS_ADD_REMOVE_PROGRAMS.MachineID = v_R_System.ItemKey  

 

Now replace MachineID with ResourceID and run the query again. The error for MachineID is now gone, and we just have the four other errors to deal with:

QueryAnalyzer18

Fixing the Error for ItemKey

The next error we need to correct is ItemKey, which is used in both the SELECT and INNER JOIN lines. If you edit the v_R_System view you will see this line in its query:

 

ALTER  VIEW dbo.v_R_System AS SELECT ItemKey As 'ResourceID', …

 

How convenient; ItemKey is also aliased as ResourceID. This is because both ItemKey and MachineID contain the same data, which is a unique serial number that is given to each SMS client. In some tables it is put in a column named ItemKey and in others it is in a column named ResourceID. The really cool thing is that if you look at the columns for most of the views, a lot of them have ResourceID as a column. This was done intentionally by the SMS Developers so that you could use ResourceID to link different views with a join.

 

So logically, we need to replace ItemKey with ResourceID in our query to reference the correct column name. Once we do that and run the query, we’ll be down to the last two errors that we need to fix:

QueryAnalyzer19

Fixing the Error for DisplayName00

This last error that we need to resolve is referenced twice in both the SELECT and WHERE lines, and it is actually very simple to fix. Expand the columns for the view v_GS_ADD_REMOVE_PROGRAMS and the change that we need to make is fairly clear:

QueryAnalyzer20

So instead of DisplayName00 we need DisplayName0. Once the two changes have been done, our SQL query should now look like this:

 

select all v_R_System.ResourceID, v_R_System.Name0, v_R_System.User_Name0,

 v_GS_ADD_REMOVE_PROGRAMS.DisplayName0

 

from v_R_System

 

INNER JOIN v_GS_ADD_REMOVE_PROGRAMS

 ON v_GS_ADD_REMOVE_PROGRAMS.ResourceID = v_R_System.ResourceID  

 

where v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 = 'Windows Internet Explorer 7'

 

When we run the query, it is finally presenting us with some results:

QueryAnalyzer21

You’re probably thinking that we’re home free and we can go ahead and copy our SQL query into a web report, but like so many other articles in this series, this one too ends in tragedy. Look at the first column. We’re getting a list of Resource IDs, but that not what we wanted when we started this whole process. Our original goal was to write an SMS web report to return the SMS Site Code, System Name, Last User Logon Name, and Add/Remove Program Display Name for any systems that have Internet Explorer 7 installed. To accomplish this, we’re going to need to get rid of ResourceID in the SELECT line and have it return the SMS Site Code instead, which is what we will be discussing in Part 7 of this article series.

Posted by bleary with no comments

Creating SMS Web Reports from SMS Queries - Part VII

Adding the SMS Site Code Column

 

In Part 6, we learned how to use the errors in our query to use the correct column names in our views. In this article, we will add the SMS Site Code to the report.

 

Out With the Bad, In With the Good

Before we add anything, we need to take away what we don’t need, namely the ResourceID column. Delete v_R_System.ResourceID from the SELECT line so that it looks like this:

 

select all v_R_System.Name0, v_R_System.User_Name0, v_GS_ADD_REMOVE_PROGRAMS.DisplayName0

 

Now we need to add the SMS Site Code, and the easiest way is to just browse the list of available views to see if an obvious choice jumps out at you. One thing that can help you narrow your search is to think about how the SMS site code is collected on the client. If it is picked up during an inventory cycle, then it will be in a view that starts with v_GS_. If it is picked up as part of SMS discovery, then it will begin with v_R. Since the SMS site code is part of the discovery process, the answer is the latter and we will be using the view v_RA_System_SMSAssignedSites. Scroll down to this view and expand its columns.

QueryAnalyzer22

There are only two columns listed for this view; we will be using SMS_Assigned_Sites0 for the SELECT line and ResourceID to join this to our other views.

 

To add this view.column name to our SELECT statement, we are going to use the drag-and-drop feature of Query Analyzer. Click on the view name dbo.v_RA_System_SMSAssignedSites and drag and drop it in between SELECT ALL and v_R_System.Name0. You will then need to type a period to distinguish it from the column name, and then drag and drop the column name SMS_Assigned_Sites0 after the period. Next, type a comma and a space to separate it from v_R_System.Name0. Finally, delete the dbo. from the beginning of the view name as its not necessary to keep it in there. Your SELECT line should now look like this:

 

select all v_RA_System_SMSAssignedSites.SMS_Assigned_Sites0, v_R_System.Name0, v_R_System.User_Name0, v_GS_ADD_REMOVE_PROGRAMS.DisplayName0

 

When we run this query later in the exercise, it will display the columns in the same order that they appear in the SELECT line which will be SMS site code, system name, user name, and Add/Remove Programs display name. If you wanted the columns in a different order, all you would need to do is to rearrange them in the SELECT line.

 

Adding an INNER JOIN

Are you ready for another error to deal with? Go ahead and run the query and you will see this message:

 

Server: Msg 107, Level 16, State 3, Line 1

The column prefix 'v_RA_System_SMSAssignedSites' does not match with a table name or alias name used in the query.

 

We’re getting this error because SQL doesn’t realize that this is a view because it’s not referenced in the FROM line. What we need to do is use an INNER JOIN to link it to v_R_System using two similar columns in each view, which happens to be the ResourceID column.

 

So now we’re going to learn how to write an INNER JOIN. The syntax for this statement is as follows:

 

INNER JOIN <view name to be joined> ON <view name to be joined.column name> = <view that is being joined to.column name>

 

In our case, <view name to be joined> is going to be v_RA_System_SMSAssignedSites, and <view that is being joined to> is v_R_System. The column names will both be ResourceID, as both views have this column. Now we’ll plug this info into our query, right after the existing INNER JOIN line. The new line should look like this:

 

INNER JOIN v_RA_System_SMSAssignedSites ON v_RA_System_SMSAssignedSites.ResourceID = v_R_System.ResourceID

 

 

…and the entire query should read as such:

 

select all v_RA_System_SMSAssignedSites.SMS_Assigned_Sites0, v_R_System.Name0, v_R_System.User_Name0, v_GS_ADD_REMOVE_PROGRAMS.DisplayName0

 

from v_R_System

 

INNER JOIN v_GS_ADD_REMOVE_PROGRAMS

 ON v_GS_ADD_REMOVE_PROGRAMS.ResourceID = v_R_System.ResourceID  

 

INNER JOIN v_RA_System_SMSAssignedSites

 ON v_RA_System_SMSAssignedSites.ResourceID = v_R_System.ResourceID

 

where v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 = 'Windows Internet Explorer 7'

 

So do you feel lucky? Well, do ya, punk? Let’s try running the query again:

QueryAnalyzer23

Congratulations, you’ve successfully converted an SMS query to a SQL query! At this point, you could paste this query into an SMS web report and it will work, but there is one last thing you can do to make the report a little more readable for your users.

 

Aliasing the Column Names

If you look at the column names in the query results, they have underscores and zeroes in the labels. With very little effort, we can use alias names to make the column names more user friendly. Let’s take a look at our existing SELECT statement:

 

select all v_RA_System_SMSAssignedSites.SMS_Assigned_Sites0, v_R_System.Name0, v_R_System.User_Name0, v_GS_ADD_REMOVE_PROGRAMS.DisplayName0

 

To add an alias, all we need to do is to add the SQL keyword AS after each column name and then enclose the alias name in single quotes. Change your SELECT line to read as follows:

 

select all v_RA_System_SMSAssignedSites.SMS_Assigned_Sites0 AS 'SMS Site',

 v_R_System.Name0 AS 'System Name',

 v_R_System.User_Name0 AS 'User Name',

 v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 AS 'Add/Remove Programs Display Name'

 

from v_R_System

 

INNER JOIN v_GS_ADD_REMOVE_PROGRAMS

 ON v_GS_ADD_REMOVE_PROGRAMS.ResourceID = v_R_System.ResourceID  

 

INNER JOIN v_RA_System_SMSAssignedSites

 ON v_RA_System_SMSAssignedSites.ResourceID = v_R_System.ResourceID

 

where v_GS_ADD_REMOVE_PROGRAMS.DisplayName0 = 'Windows Internet Explorer 7'

 

Now when you run the query, the column names reflect what you put in for each alias:

QueryAnalyzer24

All that remains now is to copy the SQL query into the SMS web report named “All Systems with Microsoft Internet Explorer 7” that we originally created back in Part 1. Highlight your SQL query text and copy it, then open the SMS Administrator Console. Expand the Reporting node, and then click on Reports. Find the report that we created and double-click on it to edit its properties. Click on the Edit SQL Statement button and delete the previous query, paste in our new and improved SQL query, and then click on OK twice. Now run the report by right-clicking on it, and then from the pop-up menu select All Tasks -> Run -> YourSMSReportingServerName. Your report should now be working and displaying rows and columns instead of rude error messages. In the screen shot below, please note that the ugly black boxes were placed over the report columns to conceal user and system names.

QueryAnalyzer25

So that’s it; you now know how to convert an SMS query into a SQL query for a web report! Thanks for taking the time to read this series of articles. I hope you’ve learned a few things that you can use in your environment and I wish you success in your querigraphing!! That would be the practice or art of writing queries, and yes, I just made that word up. But remember, you heard it here first.

 

Many kind regards,

 

Brian Leary

SMS Administrator and Querigraphist

 

 

For Further Study…

If you want to learn more about creating SMS Web Reports or SQL, you can visit these links:

 

Using SMS 2003 SQL Views to Create Custom Reports

 

SQLCourse.com

 

W3Schools SQL Tutorial

Posted by bleary with 1 comment(s)