Skip to content

Instantly share code, notes, and snippets.

@amachang
Last active July 1, 2023 15:16
Show Gist options
  • Save amachang/37dcc658e091cf226a3f7b6e2865060f to your computer and use it in GitHub Desktop.
Save amachang/37dcc658e091cf226a3f7b6e2865060f to your computer and use it in GitHub Desktop.
[Windows] Windows を触ってみる

Windows を触ってみる (Powershell メイン)

前提

GCP の Compute Engine で立ち上げた Windows を ssh 経由でログインして使う

この PowerShell が Administractor として起動されたかどうか知りたい

# Identity を取得
$CurrentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()

# Principal を new
$CurrentPrincipal = New-Object Security.Principal.WindowsPrincipal $CurrentIdentity

# Role を確認
$CurrentPrincipal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)

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

SSH サーバのインストールと設定

# オンデマンド機能 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 から操作できる。

TimeZone の設定

Set-TimeZone -Id 'Tokyo Standard Time'

Chocolatey のインストール

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 をインストールする

とりあえず、何をするにも Vim が欲しい

choco install vim

各種エンコーディングを UTF-8 にする

vim $PROFILE

$PROFILE に以下を追加

$PSDefaultParameterValues['*:Encoding'] = 'utf8'
$global:OutputEncoding = [System.Text.Encoding]::UTF8
[console]::OutputEncoding = [System.Text.Encoding]::UTF8

git のインストール

choco install git

なんか Path を作ってくれないので自分で $PROFILE をいじる

# C:\Program Files\Git\bin を env:Path に追加
vim $PROFILE

Vim の plugin

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 の準備ができたので公開鍵を登録して鍵認証で ssh できるようにする

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 ... # (同じホスト名でログインできる)

winget をインストールする

# 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 のみで使う人は少ないのだろうか。

VC を入れる

上記で書いたように 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"

VC の環境設定

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 というコマンドを叩く

C で Hello world! 書くところまでやってみる

~\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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment