Making the EmailLink Admin Console Easier to Use

As I manage my EmailLink instance, I can see a list of users being managed.  That's all well and good, but I really want to see this location within Content Manager.  This should be a link!  Same thing for all the other features.  I wish I could navigate directly to the objects.

No link to the location!

No link to the location!

By changing one line of code I can fix this up....

First I launched Notepad++ and then opened the "EmailLink\pages\users.cshtml" file.  I located the line where it outputs the table and wrapped the column within an anchor tag.

2017-10-03_14-15-29.png

I found this code on line 43:

 
<td>@userProfile.PrimarySmtpAddress</td>

I changed it to this:

 
<td><a target="_new" href="http://wg1/HPEContentManager?uri=@userProfile.Uri&t=location&lang=ln_englishus&mbd=true">@userProfile.PrimarySmtpAddress</a></td>

Then I saved the file and reloaded my EmailLInk admin console.  The column turned into a link that, when clicked, launched a new window directly to the location.

2017-10-03_14-20-31.png

So then I repeated the process for the requisite CheckIn Style template file, so that I get the exact same behavior when looking at the check-in styles themselves.

2017-10-03_14-24-45.png

Wouldn't it be cool if I could click "Duplicate for New User" as an administrator?  :)

2017-10-03_14-29-20.png

Monitor Event Server via Powershell and notify on failures

Someone posted an interesting question over on the forum: how to monitor event processing without getting directly onto the server.  The OP was searching for a way to do it via C#, but even that is unnecessary.  It's possible to do this directly from powershell.  Even better, you can schedule your powershell script and have it do something when there's a problem. 

Here's a cut-down version of a powershell script I provide to my customers.  In the example below I have it writing to the event log when there are failures and to the information log with the current counters.

$dbid = "CM"
$wrksrv = "WG1"
 
#determine where in the event logs this information will go, create if doesn't exist
$eventLogDisplayName = "HPE Content Manager Event Processor"
$eventLogSourceName = "HPE Content Manager Event Processor"
$logFileExists = Get-EventLog -ComputerName $wrksrv -list | Where-Object {$_.logdisplayname -eq $eventLogDisplayName} 
if (! $logFileExists) {
    New-EventLog -ComputerName $wrksrv -LogName $eventLogDisplayName -Source $eventLogSourceName
}
 
#import CM namespace, create threaded database connection 
Add-Type -Path "C:\Program Files\Hewlett Packard Enterprise\Content Manager\HP.HPTRIM.SDK.dll"
[HP.HPTRIM.SDK.Database]::AllowAccessFromMultipleThreads = $true
$db = New-Object HP.HPTRIM.SDK.Database
$db.Id = $dbid
$db.WorkgroupServerName = $wrksrv
$db.Connect
 
#create an event monitor with refresh interval -- not should not really be any less than the interval defined in the event processing properties
$monitor = New-Object HP.HPTRIM.SDK.EventMonitor -ArgumentList $db, 500
#store list of what is processing and then tell it we want stats
$processors = $monitor.GetAvailableProcessors()
foreach ( $p in $processors ) {
    $monitor.EnableCounters($p)
}
#start gathering stats
$guid = $monitor.Initialise()
#give the event processor some time to process
Start-Sleep -Seconds 1
if ( $monitor.IsAlive() ) {
    foreach ( $p in $processors ) {
        #look for failure results
        $counters = $monitor.GetResults($p)
        $failed = $counters.FailedEvents()
        $queued = $counters.QueuedEvents()
        $processed = $counters.ProcessedEvents()
        if ( $failed -gt 0 ) {
            Write-EventLog -ComputerName $wrksrv -LogName $eventLogDisplayName -Source $eventLogSourceName -EntryType Error -EventId 1 -Message "Detected $($failed) Failed Events"
        }
        if ( $processed -gt 0 ) {
            Write-EventLog -ComputerName $wrksrv -LogName $eventLogDisplayName -Source $eventLogSourceName -EntryType Information -EventId 1 -Message "Detected $($processed) Processed Events"
        }
 
    }
}
               

As a CM administrator, I can install Server Manager on my local Windows 10 workstation.  When I'm in the Server Manager I can use standard windows servers features (instead of custom or third party products) to manage the environment.

The highlighted entry is the one created by the powershell script

The highlighted entry is the one created by the powershell script

Extracting Webdrawer User Queries

Content Manager does now capture user queries into the workgroup server logs, but it doesn't give you any information about Webdrawer.  Luckily IIS comes to the rescue via the site logs automatically enabled on the server.  Every time a user requests a resource from the IIS site, an entry is added to the daily log file contained inside W3SVC directory in the "c:\inetpub\logs\LogFiles" folder (or wherever your techie has redirected those logs to).

These logs can be parsed by a host of applications.  A quick google search yields a treasure trove of free applications that can analyze these logs and expose important information.  What they lack though is the unique signature of record queries.  

We can use Powershell to target just the record queries though!

2017-09-13_8-28-07.png

After running the Powershell script, I can see that there have been 51 searches for "All" records and 17 searches for "Registered On=This Year".  Right now this PowerShell script is simply writing to my screen, but in a later post we'll do much much more!  For instance, I'll write the results to a file within my Webdrawer instance.... so that the main landing page provides a direct link to the top 5 searches people perform (obviating the need for users to always use the awkward search interface).

My PowerShell script is as follows:

$queries = [ordered]@{}
$sourceDir = 'C:\inetpub\logs\LogFiles\W3SVC1'
$logs = Get-ChildItem $sourceDir -Filter *.log
foreach ( $log in $logs ) 
{
    $content = get-content "$($sourceDir)\$($log)" |%{$_ -replace '#Fields: ', ''} |?{$_ -notmatch '^#'} | ConvertFrom-Csv -Delimiter ' '
    foreach ( $entry in $content ) 
    {
        if ( $entry.'cs-uri-stem' -like '*/Record' ) 
        {
            if ( $queries.Contains($entry.'cs-uri-query') ) 
            {
                $queries[$entry.'cs-uri-query']++
            } else {
                $queries.Add($entry.'cs-uri-query',1)
            }
        }
    }
}
$queries | Format-Table