diff --git a/bin/sync-winhosts.py b/bin/sync-winhosts.py
new file mode 100755
index 0000000000000000000000000000000000000000..07483fa044b4aefaf136c955625b7e87ac8c6d8a
--- /dev/null
+++ b/bin/sync-winhosts.py
@@ -0,0 +1,217 @@
+#!/usr/bin/env python3
+
+import lib_path
+import lib
+#import dphysldap
+import ssl
+import os
+
+from datetime import datetime
+from itertools import count, filterfalse
+from ldap3 import Server, Connection, ALL, Tls, SASL, GSSAPI, ServerPool, RANDOM
+
+# ldap                  = dphysldap.Ldap(ca_certs_file=".\\ca-certificates.crt")
+main_windows_netgroup = "windows"
+windows_log_path      = "c:\\scratch\\"
+unix_log_path         = "/var/log/"
+log_file              = "sync-winhost.log"
+ca_certs_file         = "/etc/ssl/certs/ca-certificates.crt"
+
+def connect_ldap(server_names, base):
+    """Connet to the ldap server"""
+    server_names = server_names
+    base = base
+    tls = Tls(
+        validate=ssl.CERT_REQUIRED,
+        version=ssl.PROTOCOL_TLSv1_2,
+        ca_certs_file=ca_certs_file)
+    servers = [Server(s, tls=tls, get_info=ALL) for s in server_names]
+    server_pool = ServerPool(
+        servers,
+        pool_strategy=RANDOM,
+        active=True,
+        exhaust=False)
+    connection = Connection(
+        server_pool,
+        user='ldapadmin/phd-systemxen.ethz.ch',
+        authentication=SASL,
+        sasl_mechanism=GSSAPI,
+        auto_bind='NONE',
+        version=3,
+        client_strategy='SYNC')
+    connection.open()
+    connection.start_tls()
+    connection.bind()
+    user_classes = ['posixAccount', 'dphysUser', 'inetOrgPerson', 'shadowAccount']
+    group_classes = ['posixGroup', 'dphysGroup']
+    obj_user = None
+    obj_group = None
+
+    return connection
+
+def get_netgroups(cn_name):
+    """Get the nisnetgroups"""
+    windows_netgroups = []
+
+    search_filter = "(&(objectClass=nisNetgroup)(cn="+ cn_name +"))"
+    ldap.search(search_base="ou=netgroup,dc=phys,dc=ethz,dc=ch", search_filter=search_filter, attributes=['memberNisNetgroup'])
+    found_groups = ldap.entries
+
+    for found_group in found_groups:
+        windows_netgroups += found_group['memberNisNetgroup']
+
+    return windows_netgroups
+
+def get_netgroup_members(group_name):
+    """Get windows clients of specific nisnetgroup"""
+    windows_clients = []
+
+    search_filter = "(&(objectClass=nisNetgroup)(cn="+ group_name +"))"
+    ldap.search(search_base="ou=netgroup,dc=phys,dc=ethz,dc=ch", search_filter=search_filter, attributes=['nisNetgroupTriple'])
+    found_groups = ldap.entries
+
+    for found_group in found_groups:
+        for client_fqdn in found_group['nisNetgroupTriple']:
+            client_temp = client_fqdn.replace('(','')
+            client_ldap = client_temp.replace('.ethz.ch,-,-)','') + '$'
+            windows_clients.append(client_ldap)
+
+    return windows_clients
+
+def get_netgroup_clients(main_windows_netgroup):
+    """Get all windows clients from nisnetgroup"""
+    clients_netgroup = []
+
+    windows_netgroups = get_netgroups(main_windows_netgroup)
+
+    for windows_netgroup in windows_netgroups:
+        clients_netgroup += get_netgroup_members(windows_netgroup)
+
+    return clients_netgroup
+
+
+def get_ldap_clients():
+    """Get Windows clients in LDAP"""
+    windows_clients = []
+
+    search_filter = "(objectClass=device)"
+    ldap.search(search_base="ou=ad,dc=phys,dc=ethz,dc=ch", search_filter=search_filter, attributes=['cn'])
+    found_clients = ldap.entries
+
+    for client in found_clients:
+        windows_clients.append(str(client['cn']))
+
+    return windows_clients
+
+def sync_clients(clients_netgroup, clients_ldap):
+    """Synchronisation der windows clients im ldap zur master db nisnetgroup"""
+    remove_clients_from_ldap(list(set(clients_ldap) - set(clients_netgroup)))
+    add_clients_to_ldap(list(set(clients_netgroup) - set(clients_ldap)))
+
+def remove_clients_from_ldap(clients):
+    """Remove old obsolet Computers"""
+    write_log("Remove " + str(len(clients)) + " clients from ldap.", True)
+    for client in clients:
+        write_output("remove client "+ client +" from ldap.....", False)
+        delete_windows_host(client)
+
+def add_clients_to_ldap(clients):
+    """Add new Windows Computers to Ldap"""
+    write_log("Add " + str(len(clients)) + " clients to ldap.", True)
+    for client in clients:
+        write_output("add client "+ client + " to ldap.....", False)
+        create_windows_host(client)
+
+def create_windows_host(computername):
+    """create windows host in ldap"""
+    hostname         = computername
+    host_dn          = "uid="+ hostname +",ou=ad,dc=phys,dc=ethz,dc=ch"
+    host_objectClass = ["device","posixAccount"]
+    host_gidNumber   = "60000"
+    host_home        = "/home/" + hostname
+    host_cn          = hostname
+    host_uidNumber   = new_uidNumber()
+    host_attrib      = {'gidNumber':host_gidNumber,'homeDirectory':host_home, 'cn':host_cn, 'uidNumber':host_uidNumber}
+
+    ldap.add(host_dn, host_objectClass, host_attrib)
+    write_output(str(ldap.result['description']), True, False)
+
+def new_uidNumber():
+    """check next free uidNumber and return it"""
+    used_nr = []
+
+    ldap.search("ou=ad,dc=phys,dc=ethz,dc=ch", search_filter="(objectClass=device)", attributes=['uid' ,'uidNumber'])
+    entries = ldap.entries
+
+    for entrie in entries:
+        nr = str(entrie['uidNumber'])
+        used_nr.append(int(nr))
+
+    free_nr = next(filterfalse(set(used_nr).__contains__, count(60001)))
+
+    return str(free_nr)
+
+def delete_windows_host(computername):
+    """remove windows host in ldap"""
+    hostname = computername
+    host_dn  = "uid="+ hostname +",ou=ad,dc=phys,dc=ethz,dc=ch"
+
+    ldap.delete(host_dn)
+    write_output(str(ldap.result['description']), True, False)
+
+def write_log(message,new_line,with_timestamp=True):
+    """write output to logfile"""
+    if os.name == "nt":
+        logfile_path = windows_log_path + log_file
+    else:
+        logfile_path = unix_log_path + log_file
+
+    if with_timestamp:
+        log_message = datetime.now().strftime('%d-%m-%Y %H:%M:%S') + ": " + message
+    else:
+        log_message = message
+
+    if new_line:
+        log_message += "\n"
+
+    f = open(logfile_path, "a+")
+    f.write(log_message)
+
+def write_output(message, new_line,with_timestamp=True):
+    """wirte output to standardout and logfile"""
+    write_log(message, new_line, with_timestamp)
+    if new_line:
+        message += "\n"
+    print(message, end='')
+
+###############
+#
+# Start Script
+#
+###############
+write_log("", True)
+write_log("Start Sync-Windowshost",True)
+write_log("",True)
+
+# LDAP Connection
+write_log("Start connection to LDAP",True)
+ldap = connect_ldap(["phd-aa1.ethz.ch","phd-aa2.ethz.ch","phd-aa3.ethz.ch"],'ou=ldap,dc=phys,dc=ethz,dc=ch')
+
+# Get all Clients from nis Netgroup
+write_log("Get from Netgroup all clients",True)
+clients_netgroup = get_netgroup_clients(main_windows_netgroup)
+#clients_netgroup = ['peter$', 'heidi$', 'geisse$']
+write_log("found "+ str(len(clients_netgroup))+ " clients in netgroup",True)
+
+# Get all Clients for LDAP
+write_log ("Get from LDAP all clients",True)
+clients_ldap = get_ldap_clients()
+write_log("found "+ str(len(clients_ldap))+ " clients in ldap",True)
+
+# Synchrnisation von netgroup auf ldap
+write_log("Start Sync",True)
+sync_clients(clients_netgroup, clients_ldap)
+
+write_log("",True)
+write_log("End Sync-Windowshost",True)
+write_log("",True)