チャブーンです。
まず、net stop コマンドですが、私の記憶の限りですけれど「同期的なコマンド」だったと思います。
同期的なコマンド、というのは (この文章での意味合いですが) 、コマンドの「完全な」実行結果が戻ってくるまで、他の処理には進まない、ということです。これに対して、コマンドを実行したら、「コマンドが正常に命令された」ことだけをチェックして、その結果を戻さない場合「非同期的なコマンド」ということがあります。
こういう場合、普通はバッチファイルに net stop [サービス名] コマンドを先に書き、shutdown コマンドを後に書けば、net stop でサービスが終了、または終了に失敗したことが戻ってきた時点で shutdown コマンドに処理が移りますので、問題はなかったと思います。
うえの考え方では、「サービスはnet stopコマンドで必ず終了する」「サービス終了に失敗してshutdownコマンドを実行しても特に問題なし」という前提のバッチファイルになってしまうので、「サービス終了に失敗したらshutdownコマンドは実行しない」としたい場合、バッチファイルの作り込みが必要になります。
ここまで書くと、「shutdown コマンドではサービス終了のためのコントロールメッセージ等もきちんと処理されるので、ほっといても問題ないのでは?」という疑問をもたれる方は必ずいらっしゃると思います。
正論としてはそのとおりなのですが、サービスアプリケーションによっては、「Windows サービスアプリケーションの作法」に添って作られていないものもあり、こういうものでは、正常なサービス終了の動作は期待できなかったり、アプリケーション側で (正常終了の扱いとならないなど) 問題が起こったりすることがあります。これを回避するため、事前に net stop コマンド (またはアプリケーションが指定する終了コマンド) で終了させておいてあげる、というテクニックが必要となることがあります。