Accidentally deleted user recovery (Active Directory & Exchange 2013)


Start with recovering user in Active Directory. Download and unzip AdRestore utility.

Run adrestore to see all deleted objects or adrestore string to filter the list by string. Find user you want to recover and run adrestore once more with /r to restore the objects – you will be propted one by one.


Now the account will reappear in Active Directoy, but will be disabled. Use what ever way you like (GUI or command line) to change password and enable account back. Add back user to the groups you want optionally.

Now move to Exchange …

If you deleted user in Active Directory, it disappears from EAC, but its mailbox state is not changed immediately in Exchange database (it changes when regular database maintanance is preformed), so we need to update it manually. To do so, we need to find mailbox GUID first.

Open Exchange Management shell and run following command to list all mailboxes details. Find GUID of the mailbox you want to recover.

Get-MailboxDatabase | Get-MailboxStatistics | Format-List DisplayName, MailboxGuid, Database, DisconnectReason, DisconnectDate

Update mailbox state for the particular mailbox, change to your Exchange database name and GUID you found in previous step.

Update-StoreMailboxState -Database “db_name” -Identity “guid”

Then go to Exchange Admin Center to Recipients / Mailboxes and click ... in the icon line and select Connect Mailbox.


Now you should see disconnected mailbox you want to recover. So select it and click connect icon.


You’ll get the warning there is no corresponding user and you must connect it to different user. It may be whatever user which does not have connected mailbox yet. That’s alright as the account you recovered in Active Directory does not have a mailbox yet. So go ahead. In the following wizard select user mailbox and later the account you recovered.

At the end you may get notification that changes made will be taken into account when Active Directory replication occurs.


If you wnat to be sure, trigger replication manually on any domain controller.

repadmin /syncall

Now you should be able to access the mailbox again.

Issues converting containers during Proxmox upgrade from 3.4 to 4.0


Super imporant step before you start with the upgrade is to check ALL your OpenVZ containers run SUPPORTED distros! Very short and hard to notice list is on Promox’s LXC wiki page.

I had to revert back to version 3.4 as most of the containers we run are based on CentOS7 and various versions of Fedora. So I have only couple of issues that appeared during upgrade and I was able to fix them:

  1. Broadcom network cards – Few warnings about bnx2 firmware missing appeared during apt-get dist-upgrade . Check the output and if you get, them install manually firmware-bnx2 manually, otherwise you will end up with no network after reboot to Promox 4.
  2. Broken network in CentOS containers – Once you convert your CentOS containers from OpenVZ to LXC, you can start the them, but you may experience limited network connectivity. It is caused by missing default gateway as old venet device may be configured to set default gateway in /etc/sysconfig/network. Change it to the device you created while converting container. You can also delete ifcfg-venet* files in /etc/sysconfig/network-scripts/ as they are no longer needed.

Subversion repositories with Apache and Active Directory [CentOS7]


Install necessary packages first.

$ yum install subversion mod_dav_svn mod_ldap python-ldap

Prepare configuration for Apache. Create a file /etc/httpd/conf.d/subversion.conf and put the content bellow into it. Change location, physical path on disk, Active Directory LDAP server and bind credentials to your particular environment.

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{HTTP_USER_AGENT} !^SVN/
RewriteRule ^(.*/)$ %0/ [R=301,L]

<Location /svn>
 DAV svn

 SVNParentPath /var/www/svn
 SVNListParentPath on
 SVNCacheTextDeltas off
 SVNCacheFullTexts off
 SVNAllowBulkUpdates on
 SVNIndexXSLT "/svnindex.xsl"
 AuthzSVNAccessFile /etc/subversion/access.conf

 Options Indexes

 AuthBasicProvider ldap
 AuthName "Memos Subversion Repositories"
 AuthType Basic
 AuthLDAPBindDN "CN=svn_user,OU=Service Accounts,DC=domain,DC=com"
 AuthLDAPBindPassword svn_user_password
 AuthLDAPURL "ldap://,DC=domain,DC=com?sAMAccountName?sub?(objectCategory=person)"
 Require valid-user

 ExpiresActive on
 ExpiresDefault access

Create a directory where Subversion data will be stored if it does not already exist:

$ mkdir -p /var/www/svn

Change the permissions of this directory to be owned (or at least writeable by Apache):

$ chown apache:apache /var/www/svn

Start Apache

$ systemctl start httpd

Now you need to setup access permissions. There is a catch. There is no simple way how to use Active Directory groups, so we need to synchronize groups from AD to local authz configuration file which we have already configured in Apache confiuration before. To do it we will use sync_ldap_groups_to_svn_authz.

Create authz file and put to the top users which will have access to all repositories (such administrators with read write access or continuos intergration user with read only access). Then put particular repositories permissions. You can already add groups from Active Directory. At the end will be part of the config file dedicated to groups definitions and at the very end the comment we will use to find out where the grous definition start. See:

admin = rw
ci = r

user1 = rw
@SVN_GROUP1 = rw

### Start generated content: LDAP Groups to Subversion Authz Groups Bridge ###

Now dowload and create synchronization script (adjust the details within).



# truncate the access file after the generated-content tag
perl -0777 -pe 's/\n\n\n### Start generated content.*//s' \
    < $SVN_CONF_DIR/access.conf \
    > $SVN_CONF_DIR/access.conf.tmp

echo "### Start generated content: LDAP Groups to Subversion Authz Groups Bridge ###" >> $SVN_CONF_DIR/access.conf.tmp

# append the latest LDAP group configuration
    --quiet --url="ldap://" \
    --bind-dn="CN=SVN,OU=Service Accounts,OU=People,DC=memos,DC=cz" --bind-password="REV-Code-673" --base-dn="OU=SVN Groups,OU=Groups,DC=memos,DC=cz" \
    --userid_attribute="sAMAccountName" | grep -v '^\[groups\]' | grep -v '^\#' | grep -v '^$' | sort >> $SVN_CONF_DIR/access.conf.tmp

mv -f $SVN_CONF_DIR/access.conf.tmp $SVN_CONF_DIR/access.conf

Run this script manually or from cron.

New skill: RPM packages


I have created my first RPM packages for Rubinius Ruby implementation. Find more in my other blog post at Zonio.

We use Rubinius at Zonio for our upcoming freebusy aggregation and lookup service which heavily depends on concurrent running workers which access calendars accounts and get (or even calculate) free busy from the calendar data. Now we can simply install RPM package instead of compiling the source code when we build production Docker images and development Vagrant boxes. 10 seconds to install RPM versus 10 minutes to compile the source code :)