GCP の Compute Engine で立ち上げた Windows を ssh 経由でログインして使う
# Identity を取得
$CurrentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
# Principal を new
$CurrentPrincipal = New-Object Security.Principal.WindowsPrincipal $CurrentIdentity
# Role を確認
$CurrentPrincipal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
# Verb は起動モードみたいなもので比較的雑多。 RunAs は Administrator として起動する
Start-Process powershell -Verb RunAs
オンデマンド機能とは powershell 上では WindowsCapability と呼ばれている、オプションとして付けられる Windows の OS の機能拡張みたいなもの。サーバソフトウェアを追加するのと何が違うかはいまいちわかってないけど、 OS の深い部分と連携するみたいなものだろうか。
以下は、 OpenSSH サーバーをインストールしたいので、オンデマンド機能を grep っぽい感じで探す。 grep とは違ってオブジェクトのストリームとして処理できるので嬉しい。
Get-WindowsCapability -Online | Where-Object Name -match 'OpenSSH'
以下は見つけた OpenSSH サーバーをインストールしている
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# オンデマンド機能 OpenSSH サーバーの Name を知る
Get-WindowsCapability -Online | Where-Object Name -match 'OpenSSH.Server'
# オンデマンド機能 OpenSSH サーバーの追加
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# sshd サービスの存在と Status を確認
Get-Service | Where-Object Name -match 'sshd'
# sshd の起動
Start-Service sshd
# 確認したことを確認
Get-Service | Where-Object Name -match 'sshd'
# ファイアウォールの設定を確認(Enabled が True 、 Direction が Inbound 、 Action が Allow になってることを確認)
Get-NetFirewallRule | Where-Object Name -match 'OpenSSH-Server-In-TCP'
# TCP の Port が開いてることを確認
Show-NetFirewallRule | Where-Object Name -match 'OpenSSH-Server-In-TCP' | Get-NetFirewallPortFilter
# 再起動時に sshd が起動するようにする
Set-Service -Name sshd -StartupType 'Automatic'
# Automatic になってることを確認
(Get-Service -Name sshd).StartType
# ログインシェルを PowerShell にする
$PowershellPath = (Get-Command powershell).Source # powershell.exe のパス取得
$PowershellPath # 確認
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value $PowershellPath -PropertyType String -Force # レジストリに追加
リモートでログインできるようになったので、ここからは手元の mac から操作できる。
Set-TimeZone -Id 'Tokyo Standard Time'
Chocolatey というパッケージマネージャがあるっぽいので使ってみる
https://chocolatey.org/install#individual
上記の URL で Individual Use を選択したら出てくるコマンドを実行
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
プロファイルファイルに Path を書く
# プロファイルファイルがあるか確認
Get-Content $PROFILE
# なかったら作る
New-Item -Type File -Path $PROFILE -Force
# Path を通す
"`$env:Path += `";C:\ProgramData\chocolatey\bin`"" | Out-File -Append -FilePath $PROFILE -Encoding utf8
# Path を確認
Get-Content $PROFILE
シェルを再起動するためにログアウトログインする
# Chocolatey が動くか確認
choco
とりあえず、何をするにも Vim が欲しい
choco install vim
vim $PROFILE
$PROFILE に以下を追加
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
$global:OutputEncoding = [System.Text.Encoding]::UTF8
[console]::OutputEncoding = [System.Text.Encoding]::UTF8
choco install git
なんか Path を作ってくれないので自分で $PROFILE をいじる
# C:\Program Files\Git\bin を env:Path に追加
vim $PROFILE
vim のディレクトリのパスが mac とか linux と違うので注意 Vundle は使えなかったので、 NeoBundle を使った
mkdir ~\vimfiles
mkdir ~\vimfiles\bundle
git clone https://github.com/Shougo/neobundle.vim ~\vimfiles\bundle\neobundle.vim
以下のように ~/.vim なところは ~/vimfiles として syntastic と rust のハイライトを入れる。
set nocompatible
filetype off " for NeoBundle
if has('vim_starting')
set rtp+=$HOME/vimfiles/bundle/neobundle.vim/
endif
call neobundle#begin(expand('~/vimfiles/bundle'))
NeoBundleFetch 'Shougo/neobundle.vim'
NeoBundle 'vim-syntastic/syntastic'
NeoBundle 'rust-lang/rust.vim', {'autoload': {'filetypes': ['rust']}}
call neobundle#end()
filetype plugin indent on " restore filetype
syntax on
set nu
set expandtab
set tabstop=4
set softtabstop=4
set shiftwidth=4
set incsearch
set backspace=indent,eol,start
上のように _vimrc を書いて保存してもう一度開いて Vim のコマンドモードで :NeoBundleInstall する
vim $env:ProgramData\ssh\sshd_config
以下の行をコメントインする
PubkeyAuthentication yes
Sshd を再起動
Restart-Service -Name sshd
ssh でコネクションする元のマシンから以下のコマンドで設定できてるか確認
# REMOTE_HOST は windows server の host name
ssh "$REMOTE_HOST" -G | grep pubkeyauthentication
# 以下のファイルに自分の公開鍵を置く、なければファイルを作る
vim $env:ProgramData\ssh\administrators_authorized_keys
# chown とか chmod みたいなことをする
# System と Administrator のみ Full Access (F) でそのほかの設定は継承しない (/inheritance:r)
icacls $env:ProgramData\ssh\administrators_authorized_keys /inheritance:r /grant "Administrators:F" /grant
"SYSTEM:F"
Gcloud コマンドを普通に使ってて、 ~/.ssh/google_compute_engine.pub があれば、その公開鍵を登録しておくと、 IP が変わったりしても以下のコマンドで GCP のインスタンスに接続する安定的な方法を得ることができる
gcloud compute config-ssh # ~/.ssh/config をアップデート
ssh ... # (同じホスト名でログインできる)
# Xaml がないって言われるので
Invoke-WebRequest -Uri "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.3" -OutFile ./files/$time/microsoft.ui.xaml.zip
Expand-Archive -Path microsoft.ui.xaml.2.7.3.zip -DestinationPath .\microsoft.ui.xaml.2.7.3
Add-AppxPackage -Path .\microsoft.ui.xaml.2.7.3\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx
# Winget で使われているライブラリ? インストールに必要なライブラリ?
$VCLibsAppxUrl = "https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"
$VCLibsAppxFilename = $VCLibsAppxUrl.Split("/")[-1]
Invoke-WebRequest -Uri $VCLibsAppxUrl -OutFile $VCLibsAppxFilename
Add-AppxPackage -Path $VCLibsAppxFilename
# インストール用ファイルのダウンロード
$WingetMsixBundleUrl = $(Invoke-RestMethod https://api.github.com/repos/microsoft/winget-cli/releases/latest).assets.browser_download_url | Where-Object {$_.EndsWith(".msixbundle")}
$WingetMsixBundleFilename = $WingetMsixBundleUrl.Split("/")[-1]
Invoke-WebRequest -Uri $WingetMsixBundleUrl -OutFile $WingetMsixBundleFilename
# ライセンスファイル
$WingetLicenseUri = $(Invoke-RestMethod https://api.github.com/repos/microsoft/winget-cli/releases/latest).assets.browser_download_url | Where-Object {$_.EndsWith("_License1.xml")}
$WingetLicenseFilename = $WingetLicenseUri.Split("/")[-1]
Invoke-WebRequest -Uri $WingetLicenseUri -OutFile $WingetLicenseFilename
# インストール
Add-AppxProvisionedPackage -Online -PackagePath $WingetMsixBundleFilename -LicensePath $WingetLicenseFilename -Verbose
winget はコマンドだが ssh でログインすると使えなかった、 RDP などで GUI を立ち上げてないと使えないっぽい。
関連 issue: microsoft/winget-cli#698
まだ、解決していないようなので、しょうがない。完全に CUI のみで使う人は少ないのだろうか。
上記で書いたように RDP でログインして、そこで開いた Administrator Powershell で実行しないとインストールできなかった
winget install Microsoft.VisualStudio.2022.Community --silent --override "--wait --quiet --add Microsoft.VisualStudio.Workload.DataScience --add Microsoft.VisualStudio.Workload.NativeCrossPlat --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Workload.Node --add Microsoft.VisualStudio.Workload.Python --includeRecommended"
DevShell というものが何か分からないけど、おそらくコンパイラとかリンカとかに PATH を通してくれて、 INCLUDE などの環境変数を設定してくれるようなものだと思っている
vim $PROFILE
として、 PROFILE に以下のコードを入れる
Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
$VsInstanceId = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -property instanceId
Enter-VsDevShell -VsInstanceId $VsInstanceId
Visual Studio には instanceId というものがあるらしく(複数の Visual Studio を使い分けるため?)それを指定して Microsoft.VisualStudio.DevShell モジュールの Enter-VsDevShell というコマンドを叩く
~\source\repos というところにプロジェクトをおくのが Visual Studio のデフォルトの設定のようなのでそうする。
cd ~\source\repos
mkdir Hello
cd Hello
# プロジェクトのルートに CMakeLists.txt を作る
echo "cmake_minimum_required (VERSION 3.25)`nproject (HELLO)`nadd_subdirectory(src)" | Out-File -FilePath CMakeLists.txt
# ソースディレクトリを作る
mkdir src
# ソースディレクトリに hello.c を置く
echo "#include <stdio.h>`nint main() { printf(`"Hello, World!`"); }" | Out-File -FilePath src\hello.c
# hello.c を executable なファイル hello に必要な唯一のファイルとして src ディレクトリの CMakeLists.txt に定義する
echo "add_executable(hello hello.c)" | Out-File -FilePath src\CMakeLists.txt
で、ビルドする
# ビルドコマンドを動かすディレクトリは汚れるので一個ディレクトリを作る
mkdir _build
cd _build
# cmake をして、 Hello.sln とか ALL_BUILD.vcxproj というファイルを作る
cmake ..
# ALL_BUILD.vcxproj を使ってビルドする
msbuild ALL_BUILD.vcxproj
で、 hello.exe が _build/src/Debug にできるので実行
& ./src/Debug/hello
Hello, World!
a a a