Мне кажется, стоит разделять такое ПО как минимум на два компонента. Первый — собственно сама программа, которая выполняет полезный функционал, пишет лог своей работы. Второй компонент — служба, которая мониторит состояние первого компонента, перезапускает его в случае необходимости, проверяет наличие обновлений ПО и конфигов на сервере, обновляет, отправляет на сервер статистику и логи ошибок.
По поводу подводных камней — из собственного опыта — не стоит запускать много копий ПО одновременно :) Т. е. стоит четко определить условие запущенности/не запущенности программы и проверить его корректность. Сам однажды неправильно составил логическое условие в PowerShell скрипте. Память сервера переполнялась и он вис. Хоть и был удаленный доступ к машине — все равно пришлось ехать на место происшествия. Потом долго отлавливал место ошибки.