Video of the week

This is a must-watch video about one of us trying to reach the stars :-)

Well done #HRejterzy

Power.CLI (VMware) - which ESXi host to deploy a new VM

Since we've got a few ESXi hosts and over a dozen VMFS(s), it usually takes some time to choose the least overloaded host and datastore. I decided to write the following Powershell script to make this thing easier:

stats

You can download my script from here and customize it to your needs - especially the part where the password for each ESXi host is generated.

 

 

 

 

Write comment (0 Comments)

Outlook - Run a Script Rule (VBA)

I assigned myself with a task - I get a bunch of HTML-structured emails with information on Simpana backup jobs - my task was to create a script-based rule in Outlook to focus on those reports that contain information on errors.

  1. Sub BackupJobSummaryReport(olMail As Outlook.MailItem)
  2. Dim mailContent As String
  3. Dim mailHtmlBody As String
  4.  
  5. Dim allPosition As Integer
  6. Dim completedWithErrors As Integer
  7. Dim completedWithWarnings As Integer
  8. Dim unsuccessful As Integer
  9. Dim tempPos As Integer
  10.  
  11. Dim objOL As Outlook.Application
  12. Dim ns As Outlook.NameSpace
  13. Dim simpanaErrorFolder As Outlook.Folder
  14.  
  15. Dim allHtml As String
  16. Dim tdHtml As String
  17. Dim fontEndHtml As String
  18.  
  19. allHtml = "All</font></td>"
  20. tdHtml = "<td"
  21. fontEndHtml = "</font"
  22.  
  23. mailHtmlBody = olMail.HTMLBody
  24. mailContent = Replace(mailHtmlBody, Chr(34), "") ' replace e.g. colspan="1" with colspan=1
  25.  
  26. allPosition = InStr(1, mailContent, allHtml, vbBinaryCompare) ' [A]ll</font></td>
  27.  
  28. tempPos = InStr(allPosition + Len(allHtml), mailContent, tdHtml, vbBinaryCompare) ' go to [<]td ..host name..
  29. tempPos = InStr(tempPos + Len(tdHtml), mailContent, tdHtml, vbBinaryCompare) ' go to [<]td ..total..
  30. tempPos = InStr(tempPos + Len(tdHtml), mailContent, tdHtml, vbBinaryCompare) ' go to [<]td ..completed..
  31. tempPos = InStr(tempPos + Len(tdHtml), mailContent, tdHtml, vbBinaryCompare) ' go to [<]td ..completed with errors..
  32. completedWithErrors = CInt(GetValue(Mid(mailContent, tempPos, InStr(tempPos + Len(tdHtml), mailContent, fontEndHtml) - tempPos)))
  33.  
  34. tempPos = InStr(tempPos + Len(tdHtml), mailContent, tdHtml, vbBinaryCompare) ' go to [<]td ..completed with warnings..
  35. completedWithWarnings = CInt(GetValue(Mid(mailContent, tempPos, InStr(tempPos + Len(tdHtml), mailContent, fontEndHtml) - tempPos)))
  36.  
  37. tempPos = InStr(tempPos + Len(tdHtml), mailContent, tdHtml, vbBinaryCompare) ' go to [<]td ..killed..
  38.  
  39. tempPos = InStr(tempPos + Len(tdHtml), mailContent, tdHtml, vbBinaryCompare) ' go to [<]td ..unsuccessful..
  40. unsuccessful = CInt(GetValue(Mid(mailContent, tempPos, InStr(tempPos + Len(tdHtml), mailContent, fontEndHtml) - tempPos)))
  41.  
  42. If ((completedWithErrors + completedWithWarnings + unsuccessful) > 0) Then
  43. Set objOL = New Outlook.Application
  44. Set ns = Application.GetNamespace("MAPI")
  45. Set simpanaErrorFolder = ns.GetDefaultFolder(olFolderInbox).Folders("Simpana (Errors)")
  46. olMail.Move simpanaErrorFolder
  47. 'Else
  48. 'MsgBox "No error in any report found!"
  49. End If
  50. End Sub

 The script is parsing only the first row of every incoming report. The row includes the summary of all backup jobs performed by Simpana. There's one function that is missing, but it has to do with parsing so I've decided to skip it here. The most important thing here is that I use Office 365 and in newer versions (and by default) Microsoft excluded the 'run a script' option from the list of available actions to take when there's a new message in our mailbox. How to unlock this option? - you can read more HERE

 The part associated with parsing is customized since it applies to my workplace, but there are a few interesting lines showing how to move a message to a particular folder inside the Inbox folder. Here is probably the best resource on writing VBA macros I've found so far - VBOFFICE

Write comment (0 Comments)

EF Core & multilevel access

My today's task was to fetch data from three different tables via Entity Framework Core - if you're wondering how this can be done - I'm gonna show it to you with a real-life scenario. First, let me introduce the context and four C# classes that are involved (I'm including the relevant properties only):

public partial class TUser
    {
        public int AddressId { get; set; }
/* .. */
        public virtual TAddress Address { get; set; }
/* .. */
    }

public partial class TAddress
    {
        public int AddressId { get; set; }
/* .. */
        public int CountryId { get; set; }
        public int RegionId { get; set; }
/* .. */

        public virtual TAddressCountry Country { get; set; }
        /* .. */
        public virtual TAddressRegion Region { get; set; }
    }

public partial class TAddressCountry
    {  
public int CountryId { get; set; }
        public string Name { get; set; }
    }

public partial class TAddressRegion
    {  
public int RegionId { get; set; }
        public string Name { get; set; }
    }

To picture it better I decided to draw a diagram which shows proper relationships between the tables.

efcore mm

To get my list of users along with country and region names we have to incorporate both Include and ThenInclude extension methods. Include is enough when we want to query tUser table in order to get data from tAddress, however, it doesn't mean we get info on Country or Region. To get this information we need to go deeper through relationships and use ThenInclude method and in my scenario, I had to go deeper twice (Include.ThenInclude + Include.ThenInclude).

As a result I was able to fetch proper data via my API using Postman:

efcore postman

Write comment (0 Comments)

How to reIndex a mongoDB collection using PowerShell

I wanted to find a way to automatically rebuild the index of a particular mongoDB collection, but this time with kind of different approach. As I've been getting familiar with PowerShell for some time now, I wanted to write a script and resign from writing anything with the help of pure .NET technology and Visual Studio (I'm aware that PowerShell is based on .NET but it's not the same as writing code using the most popular IDE by Microsoft). To make a long story short if you want to use PowerShell cmdlet(s) to work with your mongoDB instance visit the following website - https://www.powershellgallery.com/packages/Mdbc/5.1.5 - and read more on how to work with Mdbc module written by Roman Kuzmin.

Install the module and list all the cmdlet(s) included in the package:

mdbc

If you want to read more about each of these cmdlet(s) use the following command pattern: Get-Help <Cmdlet> -Full (or use my second favorite pattern: Help <Cmdlet> -Examples)

My short script looks as follows:

phonebook

The reason why I put the database name in a red circle is to indicate, that this is the database you authenticate your mongoDB user against. If another database is used to authenticate a user then you should attach it at the end of that connection string - simply replace phonebook with the right one.

Another thing is to check if the script actually works:

powershell

And the last thing was to add it to Windows Scheduler so it could run daily:

scheduler

Write comment (0 Comments)

Debug with symbols in Visual Studio - Why does it take so long?

Be careful when using Microsoft's symbol servers - it requires some patience. If you do, well, it will take some time before you run any bigger project. You can read more about the concept here - https://docs.microsoft.com/pl-pl/azure/devops/artifacts/symbols/debug-with-symbols-visual-studio?view=vsts - like always, everything has its pros and cons. In practice, however, I definitely encourage my friends to disable this option. I've found some articles on running the projects endlessly. One was able to run after an hour of waiting until all symbols were fully loaded.

debug symbols

 

Write comment (0 Comments)