Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 55832)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 55833)
@@ -9068,4 +9068,10 @@
 
 #ifdef VBOX_WITH_GUEST_PROPS
+        /* Only load transient guest properties for configs which have saved
+         * state, because there shouldn't be any for powered off VMs. The same
+         * logic applies for snapshots, as offline snapshots shouldn't have
+         * any such properties. They confuse the code in various places.
+         * Note: can't rely on the machine state, as it isn't set yet. */
+        bool fSkipTransientGuestProperties = mSSData->strStateFilePath.isEmpty();
         /* Guest properties (optional) */
         for (settings::GuestPropertiesList::const_iterator it = data.llGuestProperties.begin();
@@ -9076,4 +9082,8 @@
             uint32_t fFlags = guestProp::NILFLAG;
             guestProp::validateFlags(prop.strFlags.c_str(), &fFlags);
+            if (   fSkipTransientGuestProperties
+                && (   fFlags & guestProp::TRANSIENT
+                    || fFlags & guestProp::TRANSRESET))
+                continue;
             HWData::GuestProperty property = { prop.strValue, (LONG64) prop.timestamp, fFlags };
             mHWData->mGuestProperties[prop.strName] = property;
@@ -10361,5 +10371,7 @@
 
             /* Remove transient guest properties at shutdown unless we
-             * are saving state */
+             * are saving state. Note that restoring snapshot intentionally
+             * keeps them, they will be removed if appropriate once the final
+             * machine state is set (as crashes etc. need to work). */
             if (   (   mData->mMachineState == MachineState_PoweredOff
                     || mData->mMachineState == MachineState_Aborted
@@ -14484,8 +14496,9 @@
     mPeer->i_setMachineState(aMachineState);
 
-    if (   aMachineState == MachineState_PoweredOff
-        || aMachineState == MachineState_Teleported
-        || aMachineState == MachineState_Aborted
-        || aMachineState == MachineState_Saved)
+    if (   oldMachineState != MachineState_RestoringSnapshot
+        && (   aMachineState == MachineState_PoweredOff
+            || aMachineState == MachineState_Teleported
+            || aMachineState == MachineState_Aborted
+            || aMachineState == MachineState_Saved))
     {
         /* the machine has stopped execution
@@ -14514,7 +14527,9 @@
         BOOL fNeedsSaving = mData->mGuestPropertiesModified;
 
+        /* remove it from the settings representation */
         settings::GuestPropertiesList &llGuestProperties = mData->pMachineConfigFile->hardwareMachine.llGuestProperties;
-        settings::GuestPropertiesList::iterator it = llGuestProperties.begin();
-        while (it != llGuestProperties.end())
+        for (settings::GuestPropertiesList::iterator it = llGuestProperties.begin();
+             it != llGuestProperties.end();
+             /*nothing*/)
         {
             const settings::GuestProperty &prop = *it;
@@ -14523,4 +14538,30 @@
             {
                 it = llGuestProperties.erase(it);
+                fNeedsSaving = true;
+            }
+            else
+            {
+                ++it;
+            }
+        }
+
+        /* Additionally remove it from the HWData representation. Required to
+         * keep everything in sync, as this is what the API keeps using. */
+        HWData::GuestPropertyMap &llHWGuestProperties = mHWData->mGuestProperties;
+        for (HWData::GuestPropertyMap::iterator it = llHWGuestProperties.begin();
+             it != llHWGuestProperties.end();
+             /*nothing*/)
+        {
+            uint32_t fFlags = it->second.mFlags;
+            if (   fFlags & guestProp::TRANSIENT
+                || fFlags & guestProp::TRANSRESET)
+            {
+                /* iterator where we need to continue after the erase call
+                 * (C++03 is a fact still, and it doesn't return the iterator
+                 * which would allow continuing) */
+                HWData::GuestPropertyMap::iterator it2 = it;
+                ++it2;
+                llHWGuestProperties.erase(it);
+                it = it2;
                 fNeedsSaving = true;
             }
