diff --git a/circle/dashboard/forms.py b/circle/dashboard/forms.py
index b2a8f4a..f3570f4 100644
--- a/circle/dashboard/forms.py
+++ b/circle/dashboard/forms.py
@@ -943,6 +943,20 @@ class VmAddInterfaceForm(forms.Form):
         return helper
 
 
+class VmDeployForm(forms.Form):
+
+    def __init__(self, *args, **kwargs):
+        choices = kwargs.pop('choices', None)
+
+        super(VmDeployForm, self).__init__(*args, **kwargs)
+
+        if choices is not None:
+            self.fields.insert(0, 'node', forms.ModelChoiceField(
+                queryset=choices, label=_('Node'), help_text=_(
+                    "Deploy virtual machine to this node "
+                    "(blank allows scheduling automatically).")))
+
+
 class CircleAuthenticationForm(AuthenticationForm):
     # fields: username, password
 
diff --git a/circle/dashboard/views/vm.py b/circle/dashboard/views/vm.py
index 38f3dfe..46f08b9 100644
--- a/circle/dashboard/views/vm.py
+++ b/circle/dashboard/views/vm.py
@@ -60,7 +60,7 @@ from ..forms import (
     VmAddInterfaceForm, VmCreateDiskForm, VmDownloadDiskForm, VmSaveForm,
     VmRenewForm, VmStateChangeForm, VmListSearchForm, VmCustomizeForm,
     TransferOwnershipForm, VmDiskResizeForm, RedeployForm, VmDiskRemoveForm,
-    VmMigrateForm,
+    VmMigrateForm, VmDeployForm,
 )
 from ..models import Favourite, Profile
 
@@ -605,7 +605,6 @@ class VmStateChangeView(FormOperationMixin, VmOperationView):
     op = 'emergency_change_state'
     icon = 'legal'
     effect = 'danger'
-    show_in_toolbar = True
     form_class = VmStateChangeForm
     wait_for_result = 0.5
 
@@ -628,9 +627,23 @@ class RedeployView(FormOperationMixin, VmOperationView):
     wait_for_result = 0.5
 
 
+class VmDeployView(FormOperationMixin, VmOperationView):
+    op = 'deploy'
+    icon = 'play'
+    effect = 'success'
+    form_class = VmDeployForm
+
+    def get_form_kwargs(self):
+        kwargs = super(VmOperationView, self).get_form_kwargs()
+        if self.request.user.is_superuser:
+            online = (n.pk for n in
+                      Node.objects.filter(enabled=True) if n.online)
+            kwargs['choices'] = Node.objects.filter(pk__in=online)
+        return kwargs
+
+
 vm_ops = OrderedDict([
-    ('deploy', VmOperationView.factory(
-        op='deploy', icon='play', effect='success')),
+    ('deploy', VmDeployView),
     ('wake_up', VmOperationView.factory(
         op='wake_up', icon='sun-o', effect='success')),
     ('sleep', VmOperationView.factory(
diff --git a/circle/vm/operations.py b/circle/vm/operations.py
index 9555341..90daf03 100644
--- a/circle/vm/operations.py
+++ b/circle/vm/operations.py
@@ -324,10 +324,14 @@ class DeployOperation(InstanceOperation):
                           "deployed to node: %(node)s"),
             node=self.instance.node)
 
-    def _operation(self, activity):
+    def _operation(self, activity, node=None):
         # Allocate VNC port and host node
         self.instance.allocate_vnc_port()
-        self.instance.allocate_node()
+        if node is not None:
+            self.instance.node = node
+            self.instance.save()
+        else:
+            self.instance.allocate_node()
 
         # Deploy virtual images
         self.instance._deploy_disks(parent_activity=activity)