Fixing Hyper-V virtual machine import with Compare-VM

Well, I was rearranging some stuff the other day, and come to an interesting “lesson learned”, which I’ll share. 🙂

In my lab, I’ve had a Hyper-V server running Windows 2012 R2, which I finally wanted to upgrade to something newer. I’ve decided to go with the latest Windows Server Insider Preview (SA 20180), just for fun.

When trying to do an in-place upgrade, I was presented with the message “it can’t be done“, which is fine – my existing installation is with GUI, the new one will be Core.

So, evacuate everything and reinstall.

In the process, I’ve also reorganized some stuff (machines were moved to another disk, not all files were on the same place, etc.).

Installed Windows, installed Hyper-V, created VM switches, but when I tried to import it all back (from PowerShell… because I had no GUI anymore), I was presented with an error.

Error during virtual machine import was (I know – could’ve used more specific Import-VM command, which will select all the right folders and required options, but… learned something new by doing it this way!):

Import-VM -Path 'D:\VMs\azshci\azshci1\Virtual Machines\5381F80D-C752-42E0-AE26-6402B019B785.vmcx'
# Import-VM : Unable to import virtual machine due to configuration errors.  Please use Compare-VM to repair the virtual machine.
# At line:1 char:1
# + Import-VM -Path 'D:\VMs\azshci\azshci1\Virtual Machines\5381F80D-C752-42E0-AE26-6402B019B785.vmcx'
# + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#     + CategoryInfo          : InvalidOperation: (:) [Import-VM], VirtualizationException
#     + FullyQualifiedErrorId : OperationFailed,Microsoft.HyperV.PowerShell.Commands.ImportVM

So, the error says it all – “Please use Compare-VM to repair the virtual machine.” 🙂

But how?! 🙂

If you go to the docs page of Compare-VM, you can see how it’s used.

And, in my case, the whole process of repairing this virtual machine looks like this:

# create an incompatibility report for a virtual machine
$report = Compare-VM -Path 'D:\VMs\azshci\azshci1\Virtual Machines\5381F80D-C752-42E0-AE26-6402B019B785.vmcx'

# check the created report as some incompatibilities were found
# VM                 : VirtualMachine (Name = 'azshci1') [Id = '5381F80D-C752-42E0-AE26-6402B019B785']
# OperationType      : ImportVirtualMachine
# ...
# Incompatibilities  : {40010, 40010, 40010, 40010}
# ...

# check what exactly is incompatible (VHD locations, in this case)
$report.Incompatibilities.Source | Format-Table
# VMName  ControllerType ControllerNumber ControllerLocation DiskNumber Path
# ------  -------------- ---------------- ------------------ ---------- ----
# azshci1 SCSI           0                0                             C:\VMs\azshci\azshci1\azshci1_0_0.vhdx
# azshci1 SCSI           1                0                             C:\VMs\azshci\azshci1\azshci1_1_0.vhdx
# azshci1 SCSI           1                1                             C:\VMs\azshci\azshci1\azshci1_1_1.vhdx
# azshci1 SCSI           1                2                             C:\VMs\azshci\azshci1\azshci1_1_2.vhdx

# fixing the VHD locations (by replacing C: with D: for all VHDs)
$report.Incompatibilities[0].Source | Set-VMHardDiskDrive -Path 'D:\VMs\azshci\azshci1\azshci1_0_0.vhdx'
$report.Incompatibilities[1].Source | Set-VMHardDiskDrive -Path 'D:\VMs\azshci\azshci1\azshci1_1_0.vhdx'
$report.Incompatibilities[2].Source | Set-VMHardDiskDrive -Path 'D:\VMs\azshci\azshci1\azshci1_1_1.vhdx'
$report.Incompatibilities[3].Source | Set-VMHardDiskDrive -Path 'D:\VMs\azshci\azshci1\azshci1_1_2.vhdx'

# recheck if all looks fine
$report.Incompatibilities.Source | Format-Table
# VMName  ControllerType ControllerNumber ControllerLocation DiskNumber Path
# ------  -------------- ---------------- ------------------ ---------- ----
# azshci1 SCSI           0                0                             D:\VMs\azshci\azshci1\azshci1_0_0.vhdx
# azshci1 SCSI           1                0                             D:\VMs\azshci\azshci1\azshci1_1_0.vhdx
# azshci1 SCSI           1                1                             D:\VMs\azshci\azshci1\azshci1_1_1.vhdx
# azshci1 SCSI           1                2                             D:\VMs\azshci\azshci1\azshci1_1_2.vhdx

# import the fixed virtual machine (success!)
Import-VM -CompatibilityReport $report
# Name    State CPUUsage(%) MemoryAssigned(M) Uptime   Status             Version
# ----    ----- ----------- ----------------- ------   ------             -------
# azshci1 Off   0           0                 00:00:00 Operating normally 9.0

Hope this helps you as well!


Backing up Office 365 to S3 storage (Exoscale SOS) with Veeam

Are you backing up your Office 365? And… why not? 🙂

I’m not going into the lengthy and exhausting discussion of why you should take care of your data, even if it’s stored in something unbreakable like “the cloud”, at least not in this post. I would like to focus on one of the features of the new Veeam Backup for Office 365 v4, which was released just the other day. This feature is “object storage support“, as you may have guessed it already from the title of this fine post!

So, this means that you can take Amazon S3, Microsoft Azure Blob Storage or even IBM Cloud Object Storage and use it for your Veeam Backup for Office 365. And even better – you can use any S3-compatible storage to do the same! How cool is that?!

To test this, I decided to use the Exoscale SOS (also S3-compatible) storage for backups of my personal Office 365 via Veeam Backup for Office 365.

I’ve created a small environment to support this test (and later production, if it works as it should) and basically done the following:

  • created a standard Windows Server 2019 VM on top of Microsoft Azure, to hold my Veeam Backup for Office 365 installation
    (good people at Microsoft provided me Azure credits, so… why not?!)
  • downloaded Veeam Backup for Office 365
    (good people at Veeam provided me NFR license for it, so I’ve used it instead of Community Edition)
  • created an Exoscale SOS bucket for my backups
    (good people at Exoscale/A1TAG/ provided me credits, so… why not?!)
  • installed Veeam Backup for Office 365
    (it’s a “Next-Next-Finish” type of installation, hard to get it wrong)
  • configured Veeam Backup for Office 365 (not so hard, if you know what you are doing and you’ve read the official docs)
    • added a new Object Storage Repository
    • added a new Backup Repository which offloads the backup data to the previously created Object Storage Repository
    • configured a custom AAD app (with the right permissions)
    • added a new Office 365 organization with AAD app and Global Admin account credentials (docs)
    • created a backup job for this Office 365 organization
    • started backing it all up

Now, a few tips on the “configuration part”:

  • Microsoft Azure:
    • no real prerequisites and tips here – simple Windows VM, on which I’m installing the downloaded software (there is a list of system requirements if want to make sure it’s all “by the book”)
  • Exoscale:
    • creating the Exoscale SOS bucket is relatively easy, once you have your account (you can request a trial here) – you choose the bucket name and zone in which data will be stored and… voilà:

    • if you need to make adjustments to the ACL of the bucket, you can (quick ACL with private setting is just fine for this one):

    • to access your bucket from Veeam, you’ll need your API keys, which you can find in the Account – Profile – API keys section:

    • one other thing you’ll need from this section is the Storage API Endpoint, which depends on the zone you’ve created your bucket in (mine was created inside AT-VIE-1 zone, so my endpoint is

  • Office 365:
    • note: I’m using the Modern authentication option because of MFA on my tenant and… it’s the right way to do it!
    • for this, I created a custom application in Azure Active Directory (AAD) (under App registrations – New registration) (take a note of the Application (client) ID, as you will need it when configuring Veeam):

    • I’ve added a secret (which you should also take a note of, because you’ll need it later) to this app:

    • then, I’ve added the minimal required API permissions to this app (as per the official docs) – but note that the official docs have an error (at this time), which I reported to Veeam – you’ll need the SharePoint Online API access permissions even if you don’t use the certificate based authentication(!) – so, the permissions which work for me are:

    • UPDATE: Got back the word from Veeam development – additional SharePoint permissions may not be necessary after all, maybe I needed to wait a bit longer… will retry next time without those permissions. 🙂
    • after that, I’ve enabled the “legacy authentication protocols”, which is still a requirement (you can do it in Office 365 admin center – SharePoint admin center – Access Control – Apps that don’t use modern authentication – Allow access or via PowerShell command “Set-SPOTenant -LegacyAuthProtocolsEnabled $True”):

    • lastly, I’ve created an app password for my (global admin) account (which will also be required for Veeam configuration):

  • Veeam Backup for Office 365:
    • add a new Object Storage Repository:

    • add a new Backup Repository (connected to the created Object Storage Repository; this local repository will only store metadata – backup data will be offloaded to the object storage and can be encrypted, if needed):

    • add a new Office 365 organization:

    • create a backup job:

    • start backing up your Office 365 data:

Any questions/difficulties with your setup?
Leave them in the comments section, I’ll be happy to help (if I can).


Figuring out your public IP address with PowerShell

Sometimes, you need to know your public IP address because of… reasons. My particular reason was creating firewall rule to limit SSH only from my current public IP address, to a machine on the Internet. And how to do it?

You can always use free services like What Is My IP?, which shows you your public IP address in a nice form:

But there are also other ways – if you’re running Linux (or WSL) and do a Google search for the command that can help you, you’ll probably get this (

curl -s | sed -e 's/.*Current IP Address: //' -e 's/<.*$//'

And if you’re using Windows, PowerShell is here to help you! I like “oneliners”, even if they are not always easy to read:

($($(Invoke-WebRequest -Uri "").ParsedHtml.getElementsByTagName('body')).innerText).TrimStart("Current IP Address: ")

I’m sure that my friend Aleksandar (PowerShell guru & Microsoft MVP) has a better way, but for me, this works just fine. 🙂

Hope it helps!


Counters missing when machines accessed remotely

Not so long ago, we observed an issue with remotely accessing the PhysicalDisk counters on several machines, more specifically – there were none. 🙂

To be clear – if you opened up the Performance Monitor (perfmon.exe) on the affected machine, you can see all the counters, including the PhysicalDisk counters. But, if you opened up the Performance Monitor on a different machine and tried to access PhysicalDisk counters of the first machine over network, they aren’t shown anymore… but others (like CPU and Memory) are still there and can be used!

Counters shown normally on local computer and in local Performance Monitor

The same counters not visible from remote machine’s Performance Monitor

So… why? 🙂

At first, we thought that our monitoring software went berserk, but no – the PhysicalDisk counters on a remote machine were missing even we were using the built-in Performance Monitor tool (PhysicalDisk counters weren’t shown).

Next – maybe it’s something on the network? Of course, network is never the issue, but still… (wasn’t an issue here as well, because other counters worked without any issues)

Next, we thought, it’s related to the version of Windows accessing from, or the version at the destination – as we found out, too many different versions were impacted to hold that theory, so… no.

One thing we are not sure is if it’s caused by some of the “not so recent security patches”.

As we found the solution for our issue, what exactly caused it in the first place is not so important right now… Solution is simple – you actually need to run one command to re-register the system performance libraries with WMI (winmgmt /resyncperf) and then reboot the affected machine.

So, the commands you need are:

winmgmt /resyncperf
shutdown /r /t 0

After that, we can access all the needed counters (PhysicalDisk) remotely again:

Counters shown normally from remote computer and in local Performance Monitor


P.S. Don’t forget to reboot the affected machine! 🙂

Show disk performance in Task Manager

One of the things that bothered me in the past was the fact that Task Manager showed all the required performance graphs, except the disk-related ones. Why is that, I don’t know. OK, you can see the disks through Resource Monitor console or PerfMon, but… I really like using Task Manager, with such nice colors and simple graphs, for a quick overall check.

So, when you’ve opened your Task Manager, you were shown something like this:


No disks. Too bad. Sad smile

But… fear not, my friend! There is a solution for this “glitch”. Even a simple one. Smile

All you need to do is run the following command in your administrative Command Prompt:

diskperf -Y

Like this:


And now, when you reopen your Task Manager, you will see following:



Windows Firewall blocking pings

A short one this time… Smile

Have you ever had an issue with Windows Firewall blocking your pings on a network using Public profile, although the “File and Printer Sharing” exception is enabled for this profile?
(oh, yes, and don’t you dare to say that Windows Firewall should be disabled by default! Smile)

So, this is what I’m talking about:


As you see in the previous picture, the exception is enabled for both profiles (this PC is not domain-joined, but it would be the same with domain-joined PC on a network which is using the Public profile). When I try to ping it, I’m getting the standard “Request timed out.” message. Why is that? Is this a feature or bug?

Well, I’ve deliberately left-out two things:

  • if I try to ping my machine from the same subnet, the ping is passing through
  • if I try to ping my machine from the different subnet (routing is all set and working OK, in case you’re wondering), the ping is not passing through

The security feature that enables this kind of behavior is set in Windows Firewall by default – by default, Windows Firewall allows ping (and other traffic) only from the Local subnet, for all networks that use the Public profile. Of course, you may want to change this in certain scenarios (and you can… easily).


This is yet another thing that should be kept in mind during troubleshooting, right? (hope it helps) Smile

Have a great weekend!

Resetting the switch – the harder way

Do you remember the (good) old Catalyst 500 series switches from Cisco?
I don’t think that they are something special nowadays (being the end-of-sale and end-of-life products), but if they are in working condition – fine, I can use them.

(if you are wondering what I’m talking about, here’s the picture)


Anyhow, I’ve found one the other day (near mint condition), and wanted to make use of it in my lab. The only problem with it was that its password and IP and everything else was changed from factory defaults, without any note or document saying into what. Smile

So, the adventure begins…

Well, yes, you can say “But the switch works (at least the switching works). Why would any of this be a problem?”. The truth – I’ve had some spare time, and not having the complete access to my newfound piece of hardware was bugging me… Smile

The first thing I’ve tried was browsing the Cisco website for instructions on how to reset this type of switch. Note that this switch doesn’t have the ‘console’ interface, only web management. Soon I’ve found this article, explaining the whole process in great detail. Following the official instructions, I’ve come to the the part where my PC had to get the dynamic IP from the switch, but it was unable to get it (my PC actually got an APIPA address, but the other side wasn’t responding to queries on

As per instructions, my switch could get either or a IP address, and I can easily set fixed IP on my PC and the problem will be solved. The thing that was bothering me is that I haven’t received the IP address from switch, as I should have and the question is why? I’ve discovered that I’m not the only one facing this issue – there’s even an article about this issue on Microsoft Answers. So, the problem seems to be in my DHCP BROADCAST flag on my PC (which is running Windows 10 Technical Preview, by the way). Long story short, the workaround provided didn’t help in my case.

And then I’ve taken another approach:

  • find out which address my switch has at the “setup time” (switch should be “talking” something during the setup, and probably a tool like WireShark or Microsoft Message Analyzer (great and free tool, by the way), can catch this “talk”)
  • set up my PC to the corresponding IP
  • try to access the configuration page
  • set up the router as I want to

So I’ve set up WireShark on my PC and started capturing the traffic… a lot of traffic… traffic that needs to be filtered by something. But what should the filter be?

Not so long ago, when my girlfriend was learning for her CCNA exam, she mentioned something called Cisco Discovery Protocol (CDP) and I’ve remembered that maybe this thing can help me now… so, I’ve entered the ‘cdp’ as a filter in WireShark and voilà – now I have something that actually seems useful!


From there, I’ve explored the CDP information in these filtered packets. In there, there is something called ‘Management Addresses’, which should be just the thing I’m looking for. And it is! I’ve seen that my switch actually has an IP of! It’s also safe to say that I never would have guessed it… would you? Smile


So, now I have the IP address of the management interface on my switch, and when I try to open it using my browser, I’ve got this:


Now comes the easy part – I’ve erased the system configuration, set the new one and this switch is finally ready to be used for whatever necessary.


And this is the end of this adventure. Switch is set to factory to defaults (and then configured as needed), I’ve been using CDP and WireShark to accomplish the task, and it was such fun! Can’t wait for the next adventure! Smile

Happy reading!

Microsoft – povijest

welcometowindows Da li ste se ikada zapitali kako je Microsoft počeo raditi, kako su nastali Windowsi, što se točno događalo "tih davnih dana"?

Sigurno jeste, mnogi jesu… 🙂


p>Slučajno sam naišao na ovaj članak pa bih ga želio podijeliti s vama. Ukoliko imate nekoliko minuta slobodnog vremena, mislim da se isplati "potrošiti" ih upravo na čitanje članka…