How to Report Result of Installation in Active Directory Deployment
One of the major drawbacks of
deploying by GPO is complete lack of any centralized reporting. After
the deployment, there are two ways to find out if it was successful – by
looking into event log, and by looking into the log of the installation
itself, provided that it was enabled by group policy. Obviously, this is
a major drawback.
Deployment systems like SMS provide
reporting by means of their agent deployed at each workstation. The
agent launches the installation, watches it, and then reports return
code to the central server where it can be then analyzed.
There is however another way to
provide the reporting – by inserting custom actions in the installation
script. In this article, we will show how to build such reporting system
using transform applied to the installation package
The actions will be reporting state
of the installation to our database. We will need 3 actions – one in the
beginning will be reporting installation start; two in the end will be
reporting installation success or failure.
For starters, we will need the
database table to report to. In this article, we will be using SQL
Server, but of course it can be any database – just the matter of
connection string.
CREATE TABLE [dbo].[_GPOInstallations]
(id] [int] IDENTITY (1, 1) NOT NULL ,
[machine] [varchar] (50) NOT NULL ,
[username] [varchar] (50) NOT NULL ,
[product] [varchar] (50) NOT NULL ,
[version] [varchar] (50) NOT NULL ,
[started] [datetime] NULL ,
[finished] [datetime] NULL ,
[commited] [bit] NULL ,
[rolledback] [bit] NULL ,
[ResultingState] [tinyint] NULL
)
Here’s the plan. Our first custom
action will create new record in the database; we will get back newly
created record id and store it in a property. In the end of deferred
execution, we will place two more custom actions – one will run in case
of commit, reporting success, another in case of rollback, reporting the
failure.
Here’s the code in vbscript of the
whole script.
function dbRegStart()
On Error Resume Next
If Session.Property("REMOVE") = "ALL" Then
State = 0
else
State = 1
end if
Set cn=createobject("adodb.connection")
cn.open "Provider=SQLOLEDB;Integrated Security=SSPI;Initial
Catalog=MYDB;Data Source=MYSERVER"
ProductName = Session.Property("ProductName")
ProductVersion = Session.Property("ProductVersion")
Set rs= cn.execute("insert into _GPOInstallations(product,version,Started,
ResultingState)
select '" & ProductName & "','" & ProductVersion & "',getdate(),
" & state & " ; select
scope_identity()")
Set rs=rs.nextrecordset
NewId=cstr(rs(0))
rs.close
cn.close
set cn=nothing
Session.Property("DBNewID") = NewId
Session.Property("DBRegCommit") = NewId
Session.Property("DBRegRollback") = NewId
end function
Function DBRegCommit()
On Error Resume Next
NewId = Session.Property("CustomActionData")
If isnumeric(NewId) Then
Set cn=createobject("adodb.connection")
cn.open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Initial
Catalog=MYDB;Data
Source=MYSERVER"
cn.execute "update _GPOInstallations set
Finished=getdate(), commited=1 where id=" &
newid
cn.close
Set cn=Nothing
End If
end function
Function DBRegRollback()
On Error Resume Next
NewId = Session.Property("CustomActionData")
If isnumeric(NewId) Then
Set cn=createobject("adodb.connection")
cn.open "Provider=SQLOLEDB;Integrated Security=SSPI;Initial
Catalog=MYDB;Data
Source=MYSERVER"
If Session.Property("REMOVE") = "ALL" Then
State = 0
else
State = 1
End If
cn.execute "update _GPOInstallations set
Finished=getdate(), rolledback=1 where id=" &
Session.Property("CustomActionData")
cn.close
Set cn=Nothing
End If
end function
The first function, dbRegStart, will
be called in the beginning of the execute sequence; functions
dbRegCommit and dbRegRollback in the end of the deferred execution -
because only then it becomes known whether the installation was
committed or rolled back.
Here’s how to insert custom actions
in ORCA.
First, we save the text of the above
vbscript in a text file, for example c:\dbReg.vbs.
We open the original MSI, and start
new transform; we then go to the table Binary, and add new row; give it
any name, for instance, dbreg1. Then focus the row “Data” and specify
filename of the saved script, c:\dbreg.vbs . ORCA will read the file
contents into the table.

Now we go to the table CustomAction.
Here, we create three custom actions:

All 3 refer in the column Source to
the Name we gave in the Binary table; type 6 indicated regular custom
action; type 1542 and 1286 respectively specify execution on Commit and
on Rollback in the deferred phase. Column Target points to the
respective function within our vbscript.
Finally, we insert out custom
actions into the right places in the script.


Assuming that the very first action
in the original execute sequence had sequence number 100, we place
“DBRegStart” before it, i.e. 90; we place DBRegCommit and DBRegRollback
right before InstallFinalize.
Then we generate new transform in
ORCA, and apply it to the original MSI when deploying (tab
“Modifications” in the package dialog in the group policy). Once the
package is installed or uninstalled, new record will appear in our
database with the name of the machine, product, version, and result of
the installation. Using trivial SQL query against the database, it’s
then easy to spot workstations where the installation has failed:
Select machine from _gpoinstallations
Where
Product = ‘MyProduct’ and version = ‘1.0.0’
And isnull(rolledback,0) = 0
|