diff --git a/image_creator/os_type/windows/__init__.py b/image_creator/os_type/windows/__init__.py
index 80117c91cbc427d04743e2d83d2cf56b427d9859..f93e0b520a5eff9f52773274fe6209f89367572c 100644
--- a/image_creator/os_type/windows/__init__.py
+++ b/image_creator/os_type/windows/__init__.py
@@ -23,6 +23,7 @@ from image_creator.util import FatalError
 from image_creator.os_type.windows.vm import VM
 from image_creator.os_type.windows.registry import Registry
 from image_creator.os_type.windows.winexe import WinEXE
+from image_creator.os_type.windows.powershell import DRVINST
 
 import tempfile
 import random
@@ -174,12 +175,19 @@ class Windows(OSBase):
         # If the image is already sysprepped we cannot further customize it
         self.mount(readonly=True, silent=True)
         try:
-            self.out.output("Checking if media is sysprepped ...", False)
-            self.syspreped = self.registry.get_setup_state() > 0
+            self.out.output("Checking media state ...", False)
+            self.sysprepped = self.registry.get_setup_state() > 0
+            self.virtio_state = self._virtio_state()
             self.out.success("done")
         finally:
             self.umount(silent=True)
 
+        # If the image is sysprepped no driver mappings will be present.
+        self.systemdrive = None
+        for drive, root in self.image.g.inspect_get_drive_mappings(self.root):
+            if root == self.root:
+                self.systemdrive = drive
+
     @sysprep('Disabling IPv6 privacy extensions')
     def disable_ipv6_privacy_extensions(self):
         """Disable IPv6 privacy extensions"""
@@ -236,7 +244,7 @@ class Windows(OSBase):
 
         self.vm.rexec(r'C:\Windows\system32\sysprep\sysprep '
                       r'/quiet /generalize /oobe /shutdown')
-        self.syspreped = True
+        self.sysprepped = True
 
     @sysprep('Converting the image into a KMS client', enabled=False)
     def kms_client_setup(self):
@@ -339,15 +347,31 @@ class Windows(OSBase):
                 "Winexe not found! In order to be able to customize a Windows "
                 "image you need to have Winexe installed.")
 
-        if self.syspreped:
+        if self.sysprepped:
             raise FatalError(
                 "Microsoft's System Preparation Tool has ran on the Image. "
                 "Further image customization is not possible.")
 
+        virtio_dir = self.sysprep_params['virtio'].value
+
+        if len(self.virtio_state['viostor']) == 0 and not virtio_dir:
+            raise FatalError(
+                "The media has no VirtIO SCSI controller driver installed and "
+                "you have not specified a directory to retrieve the VirtIO "
+                "drivers from. Further image customization is not possible.")
+
+        if len(self.virtio_state['netkvm']) == 0 and not virtio_dir:
+            raise FatalError(
+                "The media has no VirtIO Ethernet Adapter driver installed and"
+                " you have not specified a directory to retrieve the VirtIO "
+                "drivers from. Further image customization is not possible.")
+
+        if virtio_dir:
+            self._install_virtio_drivers(virtio_dir)
+
         admin = self.sysprep_params['admin'].value
         timeout = self.sysprep_params['boot_timeout'].value
         shutdown_timeout = self.sysprep_params['shutdown_timeout'].value
-        virtio_dir = self.sysprep_params['virtio'].value
 
         self.out.output("Preparing media for boot ...", False)
         try:
@@ -356,26 +380,6 @@ class Windows(OSBase):
                     self._mount_error
                 raise FatalError(msg)
 
-            virtio_state = self._virtio_state()
-            if len(virtio_state['viostor']) == 0 and not virtio_dir:
-                raise FatalError(
-                    "The media has no VirtIO SCSI controller driver installed "
-                    "and you have not specified a directory to retrieve the "
-                    "VirtIO drivers from. Further image customization is not "
-                    "possible.")
-            elif len(virtio_state['viostor']) == 0:
-                self._install_viostor_driver(virtio_dir)
-
-            if len(virtio_state['netkvm']) == 0 and not virtio_dir:
-                raise FatalError(
-                    "The media has no VirtIO Ethernet Adapter driver installed"
-                    " and you have not specified a directory to retrieve the "
-                    "VirtIO drivers from. Further image customization is not "
-                    "possible.")
-
-            if virtio_dir:
-                self._install_virtio_drivers(virtio_dir)
-
             v_val = self.registry.reset_passwd(admin)
             disabled_uac = self.registry.update_uac_remote_setting(1)
             token = self._add_boot_scripts()
@@ -434,7 +438,7 @@ class Windows(OSBase):
                 if disabled_uac:
                     self.registry.update_uac_remote_setting(0)
 
-                if not self.syspreped:
+                if not self.sysprepped:
                     # Reset the old password
                     admin = self.sysprep_params['admin'].value
                     self.registry.reset_passwd(admin, v_val)
@@ -473,7 +477,7 @@ class Windows(OSBase):
             setattr(task.im_func, 'executed', True)
 
         self.out.output("Sending shut down command ...", False)
-        if not self.syspreped:
+        if not self.sysprepped:
             self._shutdown()
         self.out.success("done")
 
@@ -610,6 +614,54 @@ class Windows(OSBase):
 
         return state
 
+    def _install_virtio_drivers(self, dirname):
+
+        self.out.output('Installing virtio drivers...', False)
+
+        try:
+            if not self.mount(readonly=False, silent=True):
+                msg = "Unable to mount the media read-write. Reason: %s" % \
+                    self._mount_error
+                raise FatalError(msg)
+
+            admin = self.sysprep_params['admin'].value
+            v_val = self.registry.reset_passwd(admin)
+            self.registry.enable_autologon(admin)
+
+            self._install_viostor_driver(dirname)
+            self._upload_virtio_drivers(dirname)
+
+            remotedir = self.image.g.case_sensitive_path("%s/VirtIO" %
+                                                         self.systemroot)
+            self.image.g.write(remotedir + "/InstallDrivers.ps1",
+                               DRVINST.replace('\n', '\r\n'))
+
+            cmd = (
+                '%(drive)s:%(root)s\\System32\\WindowsPowerShell\\v1.0\\'
+                'powershell.exe -ExecutionPolicy RemoteSigned -File '
+                '%(drive)s:%(root)s\\VirtIO\\InstallDrivers.ps1 '
+                '%(drive)s:%(root)s\\Virtio' %
+                {'root': self.systemroot.replace('/', '\\'),
+                 'drive': self.systemdrive})
+
+            self.registry.runonce({'InstallDrivers': cmd})
+
+        finally:
+            self.umount(silent=True)
+
+        try:
+            self.vm.start()
+            self.out.success("started (console on VNC display: %d)" %
+                                 self.vm.display)
+        finally:
+            self.vm.stop(6000)
+            try:
+                self.mount(readonly=True, silent=True)
+                self.virtio_state = self._virtio_state()
+            finally:
+                self.umount(silent=True)
+
+
     def _install_viostor_driver(self, dirname):
         """Quick and dirty installation of the VirtIO SCSI controller driver.
         It is done to make the image boot from the VirtIO disk.
@@ -635,7 +687,7 @@ class Windows(OSBase):
         self.registry.add_viostor()
 
 
-    def _install_virtio_drivers(self, dirname):
+    def _upload_virtio_drivers(self, dirname):
         """Install the virtio drivers to the media"""
 
         virtio_dir = self.image.g.case_sensitive_path("%s/VirtIO" %
diff --git a/image_creator/os_type/windows/powershell.py b/image_creator/os_type/windows/powershell.py
new file mode 100644
index 0000000000000000000000000000000000000000..4454cbd2fb738d9916fb924c981f0387253873c4
--- /dev/null
+++ b/image_creator/os_type/windows/powershell.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2014 GRNET S.A.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""This module hosts Windows PowerShell scripts that need to be injected into
+the windows image"""
+
+DRVINST = r"""
+#requires -version 2
+
+Param([string]$dirName=$(throw "You need to provide a directory name"))
+
+if (!(Test-Path -PathType Container "$dirName")) {
+    Write-Error -Category InvalidArgument "Invalid Directory: $dirName"
+    Exit
+}
+
+foreach ($file in Get-ChildItem "$dirName" -Filter *.cat) {
+    $cert = (Get-AuthenticodeSignature $file.FullName).SignerCertificate
+    $certFile = $dirName + "\" + $file.BaseName + ".cer"
+    [System.IO.File]::WriteAllBytes($certFile, $cert.Export("Cert"))
+    CertUtil -addstore TrustedPublisher "$certFile"
+}
+
+if (Test-Path "$dirName/viostor.inf") {
+    pnputil.exe -i -a "$dirName/viostor.inf"
+}
+
+pnputil.exe -a "$dirname\*.inf"
+
+shutdown /s /t 5
+"""
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :