Kaseya Community

Version control in Kaseya?

This question is answered

Can you monitor this within Kaseya?

version control  > what versions of the software/applications are there in the circulation

Verified Answer
  • Hi  

    There are probably several ways this could be accomplished.

    We have a very simple Alert called "Application Changes" under Monitor > Alerts, this will notify you of any new applications deployed to an endpoint. 

    Alternatively, you could use an agent procedure to query either the Kaseya Database or read a value on the machine to find the current version of an application, store it as a custom field and track the changes.

    These would not be the same type of version control that you would see in GIT/github, if thats what you were looking for.

  • Hello winkel92,

    You could track the version of important software in a custom field as suggested, but you may end up with too many custom fields.

    The Kaseya vCurrApplicationInfo contains the version of every executable running around but unfortunately this is really too big to be used for "generic" application version tracking.

    And unfortunately the: windowsAddRemProg table does not carry the product version.

    As far as I know you may end up rolling up your own.

    To get you a headstart (For windows) may start from those pieces I put together and I have ABSOLUTELY not tested :-)

    An idea could be to create a procedure that:

    Runs a powershell that outputs to a text file the content of all installed apps + version.

    Add a step to Transfer the file back to the Kaseya Server.

    A procedure that processes the file (ScheduleProcedure)  

    reading the generated file and loading a custom SQL Table.

    You could then query this table in both your agent procedures or just report it using SSRS.

    A sample table

    CREATE TABLE Z_CUSTOM_AppVersions (

          ID INT IDENTITY(1,1) NOT NULL,

      AGENTGUID VARCHAR(26) NOT NULL,

          COMPUTERNAME VARCHAR(63) NOT NULL,

      DISPLAYNAME VARCHAR(255),

      DISPLAYVERSION VARCHAR(100),

      INSTALLLOCATION VARCHAR(1024),

      PUBLISHER VARCHAR(255)

          PRIMARY KEY (ID)

    );

    A sample powershell script (passing AgentGuid as parameter and the Path for the output which can go in kworking) to query installed application on a given Agent.

    param (

       [string]$agentGuid,

    [string]$agentTempFile

    )

    $computername="ALEXW8PC"

    $array = @()

    $UninstallKey=”SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall”

    $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey(‘LocalMachine’,$computername)

    $regkey=$reg.OpenSubKey($UninstallKey)

    $subkeys=$regkey.GetSubKeyNames()

    foreach($key in $subkeys){

       $thisKey=$UninstallKey+”\\”+$key

       $thisSubKey=$reg.OpenSubKey($thisKey)

       $obj = New-Object PSObject

       $obj | Add-Member -MemberType NoteProperty -Name “AgentGuid” -Value $agentGuid

       $obj | Add-Member -MemberType NoteProperty -Name “ComputerName” -Value $computername

       $obj | Add-Member -MemberType NoteProperty -Name “DisplayName” -Value $($thisSubKey.GetValue(“DisplayName”))

       $obj | Add-Member -MemberType NoteProperty -Name “DisplayVersion” -Value $($thisSubKey.GetValue(“DisplayVersion”))

       $obj | Add-Member -MemberType NoteProperty -Name “InstallLocation” -Value $($thisSubKey.GetValue(“InstallLocation”))

       $obj | Add-Member -MemberType NoteProperty -Name “Publisher” -Value $($thisSubKey.GetValue(“Publisher”))

       $array += $obj

       }

    $array | Where-Object { $_.DisplayName } | select ComputerName, DisplayName, DisplayVersion, Publisher | Export-Csv $agentTempFile

    -----------------------------------------

    A sample powershell script (passing the File to process and the AgentGuid as parameter) to load your custom table.

    -----------------------------------------

    param (

       [string]$fileWithAppVersion

       [string]$AgentGuid

    )

    function ProcessAppVersionsFile ([Data.SqlClient.SqlConnection] $OpenSQLConnection) {

    $sqlDeleteCommand = New-Object System.Data.SqlClient.SqlCommand

       $sqlDeleteCommand.Connection = $sqlConnection

    $sqlDeleteCommand.CommandText = "DELETE FROM ksubscribers.Z_CUSTOM_AppVersions Where AGENTGUID = @AgentGuid;"

       $sqlDeleteCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@AgentGuid",[Data.SQLDBType]::NVarChar, 26))) | Out-Null

       $sqlDeleteCommand.Parameters[0].Value = $AgentGuid

       $sqlDeleteCommand.ExecuteScalar()

       $sqlCommand = New-Object System.Data.SqlClient.SqlCommand

       $sqlCommand.Connection = $sqlConnection

       $sqlCommand.CommandText = "SET NOCOUNT ON; " +

           "INSERT INTO ksubscribers.Z_CUSTOM_AppVersions (AGENTGUID,COMPUTERNAME,DISPLAYNAME,DISPLAYVERSION,INSTALLLOCATION,PUBLISHER) " +

           "VALUES (@AgentGuid,@ComputerName,@DisplayName,@DisplayVersion, @InstallLoaction, @Publisher); " +

           "SELECT SCOPE_IDENTITY() as [InsertedID]; "

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@AgentGuid",[Data.SQLDBType]::NVarChar, 26))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@ComputerName",[Data.SQLDBType]::NVarChar, 63))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@DisplayName",[Data.SQLDBType]::NVarChar, 255))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@DisplayVersion",[Data.SQLDBType]::NVarChar, 100))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@InstallLoaction",[Data.SQLDBType]::NVarChar, 1024))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@Publisher",[Data.SQLDBType]::NVarChar, 255))) | Out-Null

    $csv = Import-CSV $fileWithAppVersion

       foreach ($item in $csv) {

           $sqlCommand.Parameters[0].Value = $AgentGuid

           $sqlCommand.Parameters[1].Value = $item.ComputerName

           $sqlCommand.Parameters[2].Value = $item.DisplayName

           $sqlCommand.Parameters[3].Value = $item.DisplayVersion

           $sqlCommand.Parameters[4].Value = $item.InstallLocation

           $sqlCommand.Parameters[5].Value = $item.Publisher

           $InsertedID = $sqlCommand.ExecuteScalar()

       }

    }

    $DBServer = "MySQLServerName\MyInstanceName"

    $DBName = "MyDBName"

    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection

    $sqlConnection.ConnectionString = "Server=$DBServer;Database=$DBName;Integrated Security=True;"

    $sqlConnection.Open()

    if ($sqlConnection.State -ne [Data.ConnectionState]::Open) {

       "Connection to DB is not open."

       Exit

    }

    ProcessAppVersionsFile($sqlConnection)

    if ($sqlConnection.State -eq [Data.ConnectionState]::Open) {

       $sqlConnection.Close()

    }

    -----------------------------------------

    By scheduling regularly on your agents this procedure you should be able to have something that updates regularly.

  • Thanks for the information .

    this is wat i need :)

All Replies
  • Hi  

    There are probably several ways this could be accomplished.

    We have a very simple Alert called "Application Changes" under Monitor > Alerts, this will notify you of any new applications deployed to an endpoint. 

    Alternatively, you could use an agent procedure to query either the Kaseya Database or read a value on the machine to find the current version of an application, store it as a custom field and track the changes.

    These would not be the same type of version control that you would see in GIT/github, if thats what you were looking for.

  • Hello winkel92,

    You could track the version of important software in a custom field as suggested, but you may end up with too many custom fields.

    The Kaseya vCurrApplicationInfo contains the version of every executable running around but unfortunately this is really too big to be used for "generic" application version tracking.

    And unfortunately the: windowsAddRemProg table does not carry the product version.

    As far as I know you may end up rolling up your own.

    To get you a headstart (For windows) may start from those pieces I put together and I have ABSOLUTELY not tested :-)

    An idea could be to create a procedure that:

    Runs a powershell that outputs to a text file the content of all installed apps + version.

    Add a step to Transfer the file back to the Kaseya Server.

    A procedure that processes the file (ScheduleProcedure)  

    reading the generated file and loading a custom SQL Table.

    You could then query this table in both your agent procedures or just report it using SSRS.

    A sample table

    CREATE TABLE Z_CUSTOM_AppVersions (

          ID INT IDENTITY(1,1) NOT NULL,

      AGENTGUID VARCHAR(26) NOT NULL,

          COMPUTERNAME VARCHAR(63) NOT NULL,

      DISPLAYNAME VARCHAR(255),

      DISPLAYVERSION VARCHAR(100),

      INSTALLLOCATION VARCHAR(1024),

      PUBLISHER VARCHAR(255)

          PRIMARY KEY (ID)

    );

    A sample powershell script (passing AgentGuid as parameter and the Path for the output which can go in kworking) to query installed application on a given Agent.

    param (

       [string]$agentGuid,

    [string]$agentTempFile

    )

    $computername="ALEXW8PC"

    $array = @()

    $UninstallKey=”SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall”

    $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey(‘LocalMachine’,$computername)

    $regkey=$reg.OpenSubKey($UninstallKey)

    $subkeys=$regkey.GetSubKeyNames()

    foreach($key in $subkeys){

       $thisKey=$UninstallKey+”\\”+$key

       $thisSubKey=$reg.OpenSubKey($thisKey)

       $obj = New-Object PSObject

       $obj | Add-Member -MemberType NoteProperty -Name “AgentGuid” -Value $agentGuid

       $obj | Add-Member -MemberType NoteProperty -Name “ComputerName” -Value $computername

       $obj | Add-Member -MemberType NoteProperty -Name “DisplayName” -Value $($thisSubKey.GetValue(“DisplayName”))

       $obj | Add-Member -MemberType NoteProperty -Name “DisplayVersion” -Value $($thisSubKey.GetValue(“DisplayVersion”))

       $obj | Add-Member -MemberType NoteProperty -Name “InstallLocation” -Value $($thisSubKey.GetValue(“InstallLocation”))

       $obj | Add-Member -MemberType NoteProperty -Name “Publisher” -Value $($thisSubKey.GetValue(“Publisher”))

       $array += $obj

       }

    $array | Where-Object { $_.DisplayName } | select ComputerName, DisplayName, DisplayVersion, Publisher | Export-Csv $agentTempFile

    -----------------------------------------

    A sample powershell script (passing the File to process and the AgentGuid as parameter) to load your custom table.

    -----------------------------------------

    param (

       [string]$fileWithAppVersion

       [string]$AgentGuid

    )

    function ProcessAppVersionsFile ([Data.SqlClient.SqlConnection] $OpenSQLConnection) {

    $sqlDeleteCommand = New-Object System.Data.SqlClient.SqlCommand

       $sqlDeleteCommand.Connection = $sqlConnection

    $sqlDeleteCommand.CommandText = "DELETE FROM ksubscribers.Z_CUSTOM_AppVersions Where AGENTGUID = @AgentGuid;"

       $sqlDeleteCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@AgentGuid",[Data.SQLDBType]::NVarChar, 26))) | Out-Null

       $sqlDeleteCommand.Parameters[0].Value = $AgentGuid

       $sqlDeleteCommand.ExecuteScalar()

       $sqlCommand = New-Object System.Data.SqlClient.SqlCommand

       $sqlCommand.Connection = $sqlConnection

       $sqlCommand.CommandText = "SET NOCOUNT ON; " +

           "INSERT INTO ksubscribers.Z_CUSTOM_AppVersions (AGENTGUID,COMPUTERNAME,DISPLAYNAME,DISPLAYVERSION,INSTALLLOCATION,PUBLISHER) " +

           "VALUES (@AgentGuid,@ComputerName,@DisplayName,@DisplayVersion, @InstallLoaction, @Publisher); " +

           "SELECT SCOPE_IDENTITY() as [InsertedID]; "

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@AgentGuid",[Data.SQLDBType]::NVarChar, 26))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@ComputerName",[Data.SQLDBType]::NVarChar, 63))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@DisplayName",[Data.SQLDBType]::NVarChar, 255))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@DisplayVersion",[Data.SQLDBType]::NVarChar, 100))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@InstallLoaction",[Data.SQLDBType]::NVarChar, 1024))) | Out-Null

       $sqlCommand.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@Publisher",[Data.SQLDBType]::NVarChar, 255))) | Out-Null

    $csv = Import-CSV $fileWithAppVersion

       foreach ($item in $csv) {

           $sqlCommand.Parameters[0].Value = $AgentGuid

           $sqlCommand.Parameters[1].Value = $item.ComputerName

           $sqlCommand.Parameters[2].Value = $item.DisplayName

           $sqlCommand.Parameters[3].Value = $item.DisplayVersion

           $sqlCommand.Parameters[4].Value = $item.InstallLocation

           $sqlCommand.Parameters[5].Value = $item.Publisher

           $InsertedID = $sqlCommand.ExecuteScalar()

       }

    }

    $DBServer = "MySQLServerName\MyInstanceName"

    $DBName = "MyDBName"

    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection

    $sqlConnection.ConnectionString = "Server=$DBServer;Database=$DBName;Integrated Security=True;"

    $sqlConnection.Open()

    if ($sqlConnection.State -ne [Data.ConnectionState]::Open) {

       "Connection to DB is not open."

       Exit

    }

    ProcessAppVersionsFile($sqlConnection)

    if ($sqlConnection.State -eq [Data.ConnectionState]::Open) {

       $sqlConnection.Close()

    }

    -----------------------------------------

    By scheduling regularly on your agents this procedure you should be able to have something that updates regularly.

  • Thanks for the information .

    this is wat i need :)