diff --git a/roles/lmn_vm/files/fvs.directory b/roles/lmn_fvs/files/fvs.directory
similarity index 100%
rename from roles/lmn_vm/files/fvs.directory
rename to roles/lmn_fvs/files/fvs.directory
diff --git a/roles/lmn_vm/files/fvs.menu b/roles/lmn_fvs/files/fvs.menu
similarity index 100%
rename from roles/lmn_vm/files/fvs.menu
rename to roles/lmn_fvs/files/fvs.menu
diff --git a/roles/lmn_fvs/files/lmn-sync b/roles/lmn_fvs/files/lmn-sync
new file mode 100644
index 0000000..16668f8
--- /dev/null
+++ b/roles/lmn_fvs/files/lmn-sync
@@ -0,0 +1,20 @@
+#!/usr/bin/bash
+#
+# Synchronize local program directory and desktop starters
+#
+set -eu
+
+if ! nslookup server; then
+  exit 0
+fi
+
+#[[ -d /usr/local/lmn ]] || mkdir -p /usr/local/lmn
+#rsync -rlptD --chown=pgmadmin:root --chmod=F755,D755 rsync://server:/local-program/ /usr/local/lmn
+
+RSYNC_COMMAND=$(rsync -ai --delete --exclude=mimeinfo.cache \
+	           --chown=root:root --chmod=F644,D755 "rsync://server:/desktopstarter" \
+		   /usr/local/share/applications/ | sed '/ \.\//d')
+if [[ $? -eq 0 ]] && [[ -n "${RSYNC_COMMAND}" ]]; then
+    echo "${RSYNC_COMMAND}"
+    update-desktop-database /usr/local/share/applications
+fi
diff --git a/roles/lmn_fvs/files/lmn-sync.service b/roles/lmn_fvs/files/lmn-sync.service
new file mode 100644
index 0000000..2f22cc8
--- /dev/null
+++ b/roles/lmn_fvs/files/lmn-sync.service
@@ -0,0 +1,6 @@
+[Unit]
+Description=Synchronize program data and desktop starters
+
+[Service]
+Type=simple
+ExecStart=/usr/local/sbin/lmn-sync
diff --git a/roles/lmn_fvs/files/lmn-sync.timer b/roles/lmn_fvs/files/lmn-sync.timer
new file mode 100644
index 0000000..2386de3
--- /dev/null
+++ b/roles/lmn_fvs/files/lmn-sync.timer
@@ -0,0 +1,9 @@
+[Unit]
+Description=Run lmn-sync after boot
+After=network-online.target
+
+[Timer]
+OnBootSec=0min
+
+[Install]
+WantedBy=timers.target
diff --git a/roles/lmn_fvs/handlers/main.yml b/roles/lmn_fvs/handlers/main.yml
new file mode 100644
index 0000000..8d70859
--- /dev/null
+++ b/roles/lmn_fvs/handlers/main.yml
@@ -0,0 +1,7 @@
+---
+- name: Run update-desktop-database
+  command: update-desktop-database "{{ item }}"
+  loop:
+    - /usr/local/share/applications
+    - /usr/local/share/desktop-directories
+    - /etc/xdg/menus/applications-merged
diff --git a/roles/lmn_fvs/tasks/main.yml b/roles/lmn_fvs/tasks/main.yml
index 4cd552e..ccce0c6 100644
--- a/roles/lmn_fvs/tasks/main.yml
+++ b/roles/lmn_fvs/tasks/main.yml
@@ -305,3 +305,6 @@
          text: sddm.hostName + " | <{{ ansible_date_time['date'] }}>"
          font.pointSize: config.fontSize
       }
+
+- name: Include sync
+  ansible.builtin.include_tasks: sync.yml
diff --git a/roles/lmn_fvs/tasks/sync.yml b/roles/lmn_fvs/tasks/sync.yml
new file mode 100644
index 0000000..fca5788
--- /dev/null
+++ b/roles/lmn_fvs/tasks/sync.yml
@@ -0,0 +1,56 @@
+---
+- name: Create directory for local .desktop-Files
+  ansible.builtin.file:
+    path: "{{ item }}"
+    state: directory
+    mode: 0755
+  loop:
+    - /usr/local/share/applications
+    - /usr/local/share/desktop-directories
+  notify: Run update-desktop-database
+
+- name: Copy fvs.directory
+  ansible.builtin.copy:
+    src: fvs.directory
+    dest: /usr/local/share/desktop-directories/
+  notify: Run update-desktop-database
+
+- name: Copy fvs.menu
+  ansible.builtin.copy:
+    src: fvs.menu
+    dest: /etc/xdg/menus/applications-merged/
+  notify: Run update-desktop-database
+
+- name: Copy lmn-sync script
+  ansible.builtin.copy:
+    src: lmn-sync
+    dest: /usr/local/sbin/
+    mode: 0755
+  register: lmn_sync
+
+- name: Run lmn-sync script
+  ansible.builtin.shell: /usr/local/sbin/lmn-sync
+  when: lmn_sync.changed
+
+- name: Deploy sudo configurations (lmn-sync for role-teacher)
+  ansible.builtin.copy:
+    dest: /etc/sudoers.d/90-lmn-sync
+    owner: root
+    group: root
+    mode: '0700'
+    content: |
+      %role-teacher ALL=(root) NOPASSWD: /usr/local/sbin/lmn-sync
+
+- name: Provide lmn-sync service and timer
+  copy:
+    src: "{{ item }}"
+    dest: "/etc/systemd/system/{{ item }}"
+    mode: 0644
+  loop:
+    - lmn-sync.service
+    - lmn-sync.timer
+
+- name: Enable lmn-sync.timer
+  systemd:
+    name: lmn-sync.timer
+    enabled: true
diff --git a/roles/lmn_vm/files/vm-run b/roles/lmn_vm/files/vm-run
index 1200b39..9e24290 100755
--- a/roles/lmn_vm/files/vm-run
+++ b/roles/lmn_vm/files/vm-run
@@ -301,7 +301,6 @@ if  ! virsh --connect="${QEMU}" list | grep "${VM_NAME}-clone"; then
     echo "VM not yet running."
     # only when school-network is reachable
     if nslookup "${SEEDBOX_HOST}"; then
-      sudo /usr/local/bin/desktop-sync
       check_images
     fi
     if [[ "${NEWCLONE}" = 1 ]] || [[ ! -f "${VM_DIR}/${VM_NAME}-clone.qcow2" ]]; then
diff --git a/roles/lmn_vm/handlers/main.yml b/roles/lmn_vm/handlers/main.yml
index 8f7c2e3..9c550b0 100644
--- a/roles/lmn_vm/handlers/main.yml
+++ b/roles/lmn_vm/handlers/main.yml
@@ -7,10 +7,3 @@
   ansible.builtin.systemd_service:
     daemon_reload: true
   listen: daemon reload
-
-- name: Run update-desktop-database
-  command: update-desktop-database "{{ item }}"
-  loop:
-    - /usr/local/share/applications
-    - /usr/local/share/desktop-directories
-    - /etc/xdg/menus/applications-merged
diff --git a/roles/lmn_vm/tasks/main.yml b/roles/lmn_vm/tasks/main.yml
index 1a51811..3828007 100644
--- a/roles/lmn_vm/tasks/main.yml
+++ b/roles/lmn_vm/tasks/main.yml
@@ -268,43 +268,6 @@
       SUBSYSTEMS=="net", KERNELS=="macvtap-{{ interface[3:9] }}", MODE="0666"
       {% endfor %}
 
-- name: Create directory for local .desktop-Files
-  ansible.builtin.file:
-    path: "{{ item }}"
-    state: directory
-    mode: '0755'
-  loop:
-    - /usr/local/share/applications
-    - /usr/local/share/desktop-directories
-  notify: Run update-desktop-database
-
-- name: Copy fvs.directory
-  ansible.builtin.copy:
-    src: fvs.directory
-    dest: /usr/local/share/desktop-directories/
-  notify: Run update-desktop-database
-
-- name: Copy fvs.menu
-  ansible.builtin.copy:
-    src: fvs.menu
-    dest: /etc/xdg/menus/applications-merged/
-  notify: Run update-desktop-database
-
-- name: check if sync.desktop is installed
-  stat: path=/usr/local/share/applications/sync.desktop
-  register: syncdesktop
-
-- name: remove deprecated desktop-files
-  ansible.builtin.shell: rm -f /usr/local/share/applications/*.desktop
-  when: not syncdesktop.stat.exists
-  notify: Run update-desktop-database
-
-- name: Copy initial sync starter
-  ansible.builtin.copy:
-    src: sync.desktop
-    dest: /usr/local/share/applications/
-  notify: Run update-desktop-database
-
 - name: Start virt-manager in session mode by default
   ansible.builtin.copy:
     dest: /usr/local/bin/virt-manager