💼

新入社員PCセットアップが5分で完了!? Bash×AppleScriptで作る自動化スクリプト

に公開

インターンで作った「PCキッティング自動化スクリプト」を紹介

初めまして!文系からフルスタックエンジニアを目指している大学生のIryuと申します!!

現在医療系スタートアップでインターンをしているのですが、このタスクは記事化してもいいよと許可をいただいたということで、今回は非エンジニアの事務メンバーでも使える(コマンド操作ほぼなし) 、Mac の初期設定が自動で完了する「PCキッティング自動化スクリプト」を紹介します!

このスクリプトを作ってから、実質作業時間は 30分→5分 に短縮し、事務メンバーから好評をいただきました!予算をかけずにサクッとMacの初期設定を自動化したい人はぜひ参考にしていただくと嬉しいです!!

背景と目的

  • 手動キッティングの課題
    • いざ新入社員や貸出用 PC をセットアップするとき、パスワード入力、管理者アカウントの作成、Salck・Chrome・notionなどのダウンロードを毎回一つずつ手作業で行っていた。その為、
  • 自動化のゴール
    • 非エンジニアでも「ボタンを押すだけ」で初期設定が終わるようにする。
    • ボタンを押したら、放置するだけでいい形を目指す。

全体のアーキテクチャ

  1. Bash スクリプト (setup.sh) でキッティング処理を自動実行
  2. AppleScript で GUI ダイアログを実装し、非エンジニアに優しい操作フローを作成

それでは、まず全体のコードを掲載し、その後パートごとに理屈を解説していきます。

Bash

#!/bin/bash

SUDO_PASSWORD="examplePass"
SSID="exampleID"
PASSWORD="examplePass1"
ADMIN_USERNAME="admin"
ADMIN_FULLNAME="admin"
ADMIN_PASSWORD="examplePass2"

# sudoセッション延長用のバックグラウンドプロセス開始
(
  while true; do
    echo "$SUDO_PASSWORD" | sudo -S -v
    sleep 900  # 15分ごとに更新
  done
) &

# バックグラウンドプロセスのPIDを記録
SUDO_KEEPER_PID=$!

# スクリプト終了時にバックグラウンドプロセスを終了
trap 'kill $SUDO_KEEPER_PID' EXIT

# Wi-Fi設定スクリプト
echo "Wi-Fiに接続しています: $SSID"
networksetup -setairportnetwork en0 "$SSID" "$PASSWORD"

sleep 5

if [ $? -eq 0 ]; then
  echo "Wi-Fiに正常に接続しました"
else
  echo "Wi-Fi接続に失敗しました"
  exit 1
fi

echo "Homebrewをインストールしています..."
NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

sleep 5

# Apple Silicon用のパス設定
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

echo "アプリケーションをインストールしています..."

# Homebrew Cask経由でアプリをインストール
brew install --cask google-chrome
brew install --cask slack
brew install --cask notion
brew install --cask clipy

sleep 5

# トラックパッド設定
defaults write -g com.apple.trackpad.scaling -float 8.0
defaults write com.apple.AppleMultitouchTrackpad Clicking -bool true
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
defaults -currentHost write NSGlobalDomain com.apple.mouse.tapBehavior -int 1
defaults write com.apple.AppleMultitouchTrackpad FirstClickThreshold -int 0
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad FirstClickThreshold -int 0

sleep 5

# 管理者アカウント作成
echo "管理者アカウント '$ADMIN_USERNAME' を作成中..."
echo "$SUDO_PASSWORD" | sudo -S -v && sudo NONINTERACTIVE=1 sysadminctl -addUser "$ADMIN_USERNAME" -fullName "$ADMIN_FULLNAME" -password "$ADMIN_PASSWORD" -admin

if id "$ADMIN_USERNAME" &>/dev/null; then
    echo "管理者アカウント '$ADMIN_USERNAME' が正常に作成されました。"
else
    echo "管理者アカウントの作成に失敗しました。"
    exit 1
fi

echo "設定を反映させるために再起動が必要です。"

変数の定義(接続情報・管理者情報)

SUDO_PASSWORD="examplePass"
SSID="exampleID"
PASSWORD="examplePass1"
ADMIN_USERNAME="admin"
ADMIN_FULLNAME="admin"
ADMIN_PASSWORD="examplePass2"
  • ここでWi‑Fi の SSID/パス、管理者ユーザーの作成情報を一箇所で管理しています。設定が変わってもここだけ直せばOK!もし、非エンジニアが変更をしたくても視覚的にここを編集すればいいことがわかります。

sudoセッションの「延命」ループ

(
  while true; do
    echo "$SUDO_PASSWORD" | sudo -S -v
    sleep 900
  done
) &
SUDO_KEEPER_PID=$!
trap 'kill $SUDO_KEEPER_PID' EXIT

  • sudo の有効期限を15分おきに更新し続け、処理の途中で権限が切れて止まるのを防止。スクリプト終了時にバックグラウンドを必ず kill(trap)。
    • それでも切れるときがあるので、今後の改善点ではあります…😅
    • sudo: a terminal is required系のエラーは-sで標準入力してあげれば解決できることが多い

Wi-Fi接続

networksetup -setairportnetwork en0 "$SSID" "$PASSWORD"
  • macOS 標準の networksetup コマンドを使って、指定インターフェイス(en0)で Wi-Fi に接続。変数 $SSID と $PASSWORD に事前に設定したネットワーク情報を渡すことで、自動接続を実行。

Homebrew の導入と PATH 設定

NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Apple Script

-- 初期設定ダイアログを表示
display dialog "Macの初期設定を開始しますか?" buttons {"キャンセル", "開始"} default button "開始"
if button returned of result is "開始" then
    try
        -- ユーザーのホームディレクトリを取得
        set homeDir to do shell script "echo $HOME"
        
        -- スクリプトのフルパスを組み立て
        set scriptPath to homeDir & "/Desktop/MacSetup/setup.sh"
        
        -- quarantine 属性をチェックして、あれば削除
        set checkQuarantine to do shell script ¬
            "xattr -p com.apple.quarantine " & quoted form of scriptPath & ¬
            " 2>/dev/null || echo \"\""
        if checkQuarantine is not "" then
            do shell script "xattr -d com.apple.quarantine " & quoted form of scriptPath
        end if
        
        -- ターミナルで実行するコマンドを生成
        set terminalCommand to "chmod +x " & quoted form of scriptPath & " && " & quoted form of scriptPath
        
        with timeout of 3600 seconds
            -- Terminal でスクリプトを実行
            tell application "Terminal"
                activate
                set myTab to do script terminalCommand
                -- 実行完了まで待機
                repeat while busy of myTab
                    delay 10
                end repeat
            end tell
        end timeout
        
        -- 完了ダイアログ
        display dialog "スクリプトの処理が完了しました。" buttons {"OK"} default button "OK"
        
        -- 再起動確認ダイアログ
        display dialog "設定を反映させるために再起動しますか?" buttons {"いいえ", "はい"} default button "はい"
        if button returned of result is "はい" then
            try
                -- 管理者パスワードを定義(ハードコード)
                set adminPass to "examplePassword"
                
                -- MacSetup フォルダを削除
                set targetFolder to homeDir & "/Desktop/MacSetup"
                do shell script "rm -rf " & quoted form of targetFolder
                
                -- 現在のログインユーザー名を取得
                set userName to do shell script "whoami"
                
                -- 管理者権限で再起動実行
                do shell script "shutdown -r now" user name userName password adminPass with administrator privileges
            on error errMsg
                display dialog "再起動に失敗しました: " & errMsg buttons {"OK"} default button "OK"
            end try
        end if
        
    on error errMsg number errNum
        display dialog "エラーが発生しました: " & errMsg & " (エラー番号: " & errNum & ")" buttons {"OK"} default button "OK"
    end try
else
    display dialog "設定をキャンセルしました。" buttons {"OK"} default button "OK"
end if

初期設定開始ダイアログ

display dialog "Macの初期設定を開始しますか?" buttons {"キャンセル", "開始"} default button "開始"

- AppleScriptのdisplay dialogを使って、ユーザーに初期設定の実行可否を尋ねます。
- 「開始」が押された場合のみ、後続の自動化処理を実行します。
    - 非エンジニアでも「開始」「キャンセル」が明確に分かるUIにしています。

ユーザーのホームディレクトリ取得とスクリプトパス設定

set homeDir to do shell script "echo $HOME"
set scriptPath to homeDir & "/Desktop/MacSetup/setup.sh"
  • 現在ログインしているユーザーのホームディレクトリを取得し、そこから対象のBashスクリプト(setup.sh)のフルパスを生成します。
  • パスを固定せず動的に取得することで、どのユーザー環境でも動作します。

quarantine属性のチェックと削除

set checkQuarantine to do shell script ¬
  "xattr -p com.apple.quarantine " & quoted form of scriptPath & " 2>/dev/null || echo \"\""
if checkQuarantine is not "" then
  do shell script "xattr -d com.apple.quarantine " & quoted form of scriptPath
end if
  • macOSではインターネット経由でダウンロードしたファイルにquarantine属性が付与され、実行時に警告やブロックがかかります。
    • この処理では事前に属性が存在するかを確認し、存在する場合のみ削除します。
    • 存在しない場合は何もしないため、エラーで処理が中断するのを防げます。

ターミナルでBashスクリプト実行

set terminalCommand to "chmod +x " & quoted form of scriptPath & " && " & quoted form of scriptPath

with timeout of 3600 seconds
  tell application "Terminal"
    activate
    set myTab to do script terminalCommand
    repeat while busy of myTab
      delay 10
    end repeat
  end tell
end timeout
  • chmod +xでスクリプトに実行権限を付与し、そのままターミナルで実行します。
  • 最大3600秒(1時間)まで待機し、実行完了を確認します。
  • busyを監視することで、スクリプト完了までAppleScriptが待ち続ける仕様です。

完了通知ダイアログ

display dialog "スクリプトの処理が完了しました。" buttons {"OK"} default button "OK"
  • スクリプトの全処理が終わったことをユーザーに通知します。
  • 完了メッセージは明確に「処理完了」とだけ表示し、わかりやすさを優先しています。

再起動確認ダイアログ

display dialog "設定を反映させるために再起動しますか?" buttons {"いいえ", "はい"} default button "はい"
  • 設定反映のために再起動が必要かを確認します。
    • 「はい」が選ばれた場合のみ、後続の再起動処理へ進みます。

後片付けと再起動実行

set adminPass to "examplePassword"
set targetFolder to homeDir & "/Desktop/MacSetup"
do shell script "rm -rf " & quoted form of targetFolder

set userName to do shell script "whoami"
do shell script "shutdown -r now" user name userName password adminPass with administrator privileges
  • デスクトップ上のMacSetupフォルダを削除し、作業ファイルを後片付けします。
  • shutdown -r nowで再起動を実行します。

エラーハンドリング

on error errMsg number errNum
  display dialog "エラーが発生しました: " & errMsg & " (エラー番号: " & errNum & ")" buttons {"OK"} default button "OK"
end try
  • AppleScriptでエラーが発生した場合に、その内容とエラー番号を表示します。
    • これにより、どこで問題が起きたかをユーザーに明示できます。

まとめ

このプロジェクトを通して、BashやAppleScriptでの自動化だけでなく、「非エンジニアでも触れるUI設計(ユーザー目線)」や「保守しやすいコード構造」の重要性を学びました。

インターン中にこうした実務的な課題に挑戦できたのは、今後エンジニアとして働く上で大きな財産になったと思います。

今後も多くの失敗や経験を積み重ねながら、少しでも早く目標であるフルスタックエンジニアに近づいていきたいと思います!

Discussion