azukipochette's weblog

memory dump (mini)

Azure Pipelines の Pool を調べる

Azure DevOps 向けの拡張機能を Azure CLI にインストールし、次のコマンドを実行すればよい。 なお、事前に az login でログインしておく必要がある。

アクセスできるプールは組織 (orgnization, 旧VSTSアカウント) 次第なので、下記の結果は参考程度に見てほしい。

C:\Works>az pipelines pool list -o table
This command group is in preview. It may be changed/removed in a future release.
ID    Name                             Is Hosted    Pool Type
----  -------------------------------  -----------  -----------
1     Default                          False        automation
2     Hosted                           True         automation
4     Hosted VS2017                    True         automation
5     Hosted macOS                     True         automation
6     Hosted Ubuntu 1604               True         automation
7     Hosted Windows Container         True         automation
8     Hosted Windows 2019 with VS2019  True         automation
9     Hosted macOS High Sierra         True         automation
10    Azure Pipelines                  True         automation

なお、YAML で pool の指定をする場合の名前はこのコマンドでは取得できず、以下の URL の記載を確認する必要がある *1

docs.microsoft.com

*1:なんで取れないねん!と私は思う...

購入した製品が動かないので Microsoft と Apple から電話サポートをしてもらった話

久しぶりにブログを書こうと思ったのは、比較的短い間隔で購入した製品が動かないという不幸が続き、カスタマー サポートを Microsoft と Apple から受けたのがだ、その時の印象がだいぶ違うことに驚いたからだ。

これを読む人が同じようにサポートを受ける人なのか、サポートをする側の人なのかはわからないが、どちらにでも有益な情報になるだろうと思って書いた。ただ個人的には、サポートをする側の人たちがこの内容を見てもう少しサポートを改善しようと思ってくれると嬉しい。

Microsoft / Apple のカスタマー サポートの流れの比較

それぞれ、個人向けサポート (コンシューマー サポート) 窓口での対応の話である。企業サポートや、それ以外の対応ではサポート体制が大きく異なることがあるので、注意してほしい。

対応ステップ        Microsoft Apple
カスタマー サポートに電話する方法 Microsoft のサポートページに記載されている電話番号に連絡する。ちなみに、Windows 10 に搭載されている [問い合わせ] アプリには、個人顧客向けのリンクがないので注意。電話番号も問い合わせ内容によって複数存在するため、どれに電話をするのかは注意が必要。 サポートページより対象の製品を選び、[すぐアドバイザーと連絡したい]をクリックすればよい。このとき、何分ぐらいで連絡がとれるのかも記載がある。
電話サポートまでの流れ 音声ガイダンスに従って、問い合わせ内容を電話番号のプッシュで選択。担当窓口が対応可能になるまで少し待つ ウェブサイト上で必要な情報 (シリアル番号、問い合わせ内容) を記載したうえで、自分自身の電話番号を記入する。折り返し、担当者より電話がくる。
問題のヒアリング サポート担当者にどのような事象だったのかを話す。その際に、電話が切られてしまった場合に備えて、名前と電話番号を確認される。 アドバイザーよりWebサイトに記載した事情について詳細に話を聞かれる。たとえば、「動かない」と記載した場合には、どのように動かないのか、などについて確認される。ヒアリングが完了すると、折り返しエンジニアから連絡しますといわれてこの電話は終了。
問題の対処 ヒアリングした事象についてサポート担当者が対処方法を確認するので、しばし待つ。対処方法について説明を受け、サポート担当者と一緒に問題解決を試みる エンジニアから連絡が来る。問題の事象について再度確認を受けて齟齬がないことを確認される。エンジニアと一緒に問題解決を試みる

なお、問題の事象次第で、その後の対応については変わるため、問題の対処後については比較しない。

特記すべき体験について以下に書いておく。

Apple のアドバイザーはとにかくエモい

釣りタイトルみたいで申し訳ないが (笑)、アドバイザーの対応はとにかく低姿勢で丁寧に対応してくれる。 私の場合、Apple TV が自身の TV で接続しても画面が表示されないという問題だったわけだが、「〇〇様が Apple TV でビデオを見られると楽しみにされていたのに画面が表示されないということなのですね...それは大変申し訳ございません!」というような言葉を感情をこめて言われる。私も、「おぉぉ...この人、私の問題を理解している!」という気持ちになった。期待して購入した製品について、動かなくて「残念だ」という気持ちに対して、「残念でしたよね」と共感することは大事なのだなぁ、と改めて思った。Microsoft のサポートでも他のサポートでもそうだが、基本的には「なるほど、そうですか。」という対応で終わってしまうが、購入した製品が期待する機能をはたしていないとき、こういった対応は必要だ。

Apple のサポート体制について私は知らないが、私の予想ではアドバイザーは問題のハンドリングをしているのだと思う。つまり、アドバイザー自身が直接問題を解決するのではなく、ユーザーからヒアリングしたうえで適切な場所に誘導しているのだろう、と予想している。実際、このアドバイザーからは「どんな問題か」についてはいろいろと聞かれるが、簡単な「対処」については何も聞かれなかった。

電話受付時、事象によっては顧客は焦っていたり、怒っていたりしているだろう。そういう時にこういったアドバイザーが丁寧にそして冷静に問題を仕分け、適切な場所に振り分けるのには特殊なスキルが必要だ。それは、技術サポートとはちょっと違う。

電話口で "待つ" ということ

現在、企業は様々なサポート手段を持っている。たとえば、電話、メール、チャット、ボットなど。企業によっては Twitter などの SNS を巡回し、自社製品に不満を言っている Tweet を見つけて、対処方法を連絡するということをしていたりもする。 ただ、緊急であったり、状況や問題について整理ができていない場合、あなたは "電話サポート" を選ぶはずだ。

電話サポートにおける問題の 1 つは、その対応時間だ。これを見ている人が長電話は慣れたものかどうかはわからないが、私は日頃、スマホで 1 時間も電話などしない。今回の Microsoft の場合は、購入した商品が初期不良だったという問題だったが、こんなシンプルな問題でも結局 1 時間以上電話することになった。おそらく、サポート担当者 (オペレーター) 側はヘッドフォンなどで対応しているのだろうが、スマホというそこそこのダンベルを1時間以上耳に当てて電話をするのは大変疲れた (手がしびれて途中で諦めそうになった)。

電話を長時間にさせる原因は明らかで、すべてを電話口で対応するためだ。たとえば、上記の比較表では Microsoft は1回の電話ですべての作業が行われているが、Apple の場合はアドバイザーとそのあとのエンジニアとの 2 回に分割されている。しかも、Apple の場合は電話前に問題を伝えているので話がスムーズ (Apple 側が電話前にどのような対処をするかが明らか) なのに対して、Microsoft 側は電話口での質問に急に対応する必要がるため、時間がかかるのだ。

そう、Apple のサポートはお客様のためにも、自分たちのためにもシステムが良くできている。

担当者が変わらないという安心感

Apple のサポートで特に関心したのは、アサインされたエンジニアが開口一番に「では、私がこの問題を最後まで一緒に解決に当たらせていただきます」と言ったことだった。

サポートを受けたことがない人は「普通じゃないの?」と思ったかもしれないが、これは普通ではない。多くのサポート対応というのは電話するたびに担当者 (オペレーター) が変わるのが普通だ。このため、問い合わせごとに番号をつけて管理をし、"引継ぎ" をする。

実際、Apple の場合は 1 回の電話では解決せずにこのあと、何度も電話をすることになったが、担当者から自身に直接電話可能な電話番号を連絡してもらえたので、新たな事象などをスムーズに話すことができた (何度も対応番号を伝えたり、引継ぎできていなかった詳細について話を伝えるのは大変心が折れる)。

(おまけ)

当然、Apple の担当者も私だけを担当しているわけではないので、暇ではない。途中何度も電話をかけてもつながらないという事象に遭遇した。すると、1 - 2時間ぐらいでその担当者の上司から連絡があり、「担当者が多忙で電話に出られなくて申し訳ありません。状況は理解していますので、私もサポートさせていただきます。」と言われた。「結局、1人の担当者じゃないんかい!」というツッコミがくるかもしれないが、この人は再度事情を説明することもなく、完全に状況を理解して適切な対応をしてくれた。

結局、私の購入した Apple TV はテレビとの相性問題であるという結論を受けて、返金対応をすることになった。担当者から「せっかく買っていただいたのに大変申し訳ない、Apple に問い合わせて担当者が返品してもらってくださいと言っていたと言ってください、もしかしたらテレビ メーカーのサポートにも問合せていただくと対処方法が見つかるかもしれません」といった言葉をかけてもらった。最後まで非常に丁寧かつ親切な対応だったと思う。

面白かったのは、その話を受けて相性問題だからテレビ メーカーのサポートにも連絡しようと電話をしたら「あー、そういう "変な" デバイスはつながないでください」と言われたことだ。さすが某有名企業、としか言いようがない。

IT (ICT) サポートについて思うこと

私もこの業界にいてそこそこ長くなってきたので、IT の問題の複雑性については理解しているつもりだ。

たとえば、周辺機器の不具合の場合、「認識しない」という問題が、コンピューター側の問題 (つまり、ドライバーやソフトウェア) の問題として発生しているのか、周辺機器自体 (つまり、ハードウェア) の問題として発生しているのかが判断しにくい。 そして、そういった問題を切り分ける方法として「"別の〇〇" はありますか?」という言葉を聞くことがあるかもしれない。たとえば、テレビに映らないのであれば「別の HDMI ケーブルで接続してみていただけますか?」といったセリフだ。ただ、こういったセリフに対して、私はときどき「ん???」となることがある。

たとえば、「では、別のテレビに接続してみてください」、「では、別の Surface に接続してください」といったセリフ。普通、個人はそんなに高額なデバイスを当然のように複数持っていない。仮にそれがある可能性を期待していたのだとしても「もしあれば、なんですが...」といえば全然印象が違うのになぁ、と思った。

ちなみに、あるサポートでは「対応してないモニターなので、モニターを買いなおしてください」と言われて、お茶を吹きそうになったことすらある。心の中で、「お前なんか、購入した HEMS が動かなくて、家を買いなおせ!」と思ったのは内緒である。

おわりに

この文章を読むと、「Apple すごい!Microsoft けしからん!」と思うかもしれないが、それは事実とは違う可能性がある。なぜなら、その印象は私からの感情バイアスを受けているからだ。

実際、マイクロソフトのサポートでも素晴らしい対応をしてくれるときもあれば、そうでないときもある。それは他の企業のサポートであっても同じことだ。私が書きたかったのは「サポートの仕組み/システムを変えれば顧客体験がこんなにも違うのか」と感じたこと、そして対応の仕方や言葉一つでカスタマーサポートの印象は大きく違うのだと感じた体験を共有したかったからだ。特定の企業を批判する目的で書いたわけではないことを十分に理解してほしい。

Azure DevOps Security Namespaces/Actions

Default

AccountAdminSecurity

Name Display name
Create Create account resource
Modify Modify account resource
Read Read account resource

Analytics

Name Display name
Administer Manage analytics permissions
ExecuteUnrestrictedQuery Execute query without any restrictions on the query form
Read View analytics
ReadEuii Read EUII data
Stage Push the data to staging area

AnalyticsViews

Name Display name
Delete Delete shared Analytics views
Edit Edit shared Analytics views
Execute Execute Analytics views
ManagePermissions Manage
Read View shared Analytics views

Boards

Name Display name
ChangeMetadata Change board metadata (name, columns, rows, settings, etc)
Create Create a board
Delete Delete the board
Manage (blank)
MoveCard Add, move or remove cards in the board
View View the board

BoardsExternalIntegration

Name Display name
Read View boards external integrations
Write Write boards external integrations

Collection

Name Display name
CREATE_PROJECTS Create new projects
DELETE_FIELD Delete field from account
DIAGNOSTIC_TRACE Alter trace settings
GENERIC_READ View collection-level information
GENERIC_WRITE Edit collection-level information
MANAGE_TEMPLATE Manage process template
MANAGE_TEST_CONTROLLERS Manage test controllers
SYNCHRONIZE_READ View system synchronization information
TRIGGER_EVENT Trigger events

CrossProjectWidgetView

Name Display name
GenericRead View instance-level information

DashboardsPrivileges

Name Display name
Create Create dashboard
Delete Delete dashboard
Edit Edit dashboard
ManagePermissions ManagePermissions
MaterializeDashboards Materialize Dashboards
Read Read

DataProvider

Name Display name
Read View data provider entities

EventSubscriber

Name Display name
GENERIC_READ View
GENERIC_WRITE Edit

EventSubscription

Name Display name
CREATE_SOAP_SUBSCRIPTION Create a SOAP subscription
GENERIC_READ View
GENERIC_WRITE Edit
UNSUBSCRIBE Unsubscribe

Favorites

Name Display name
GenericRead View instance-level information
GenericWrite Edit instance-level information

Graph

Name Display name
ReadByPersonalIdentifier Read by personal identifier
ReadByPublicIdentifier Read by public identifier

Identity

Name Display name
CreateScope Create identity scopes
Delete Delete identity information
ManageMembership Manage group membership
Read View identity information
RestoreScope Restore identity scopes
Write Edit identity information

IdentityPicker

Name Display name
ReadBasic Read basic Identity Picker properties
ReadRestricted Read restricted Identity Picker properties

Job

Name Display name
Queue Queue background jobs
Read View background job information
Update Manage background jobs

Location

Name Display name
Read Read service definitions and/or access mappings.
Write Write service definitions and/or access mappings.

Process

Name Display name
AdministerProcessPermissions Administer process permissions
Create Create process
Delete Delete process
Edit Edit process
ReadProcessPermissions View Process

Project

Name Display name
ADMINISTER_BUILD Administer a build
AGILETOOLS_BACKLOG Agile backlog management.
BYPASS_PROPERTY_CACHE Bypass project property cache
BYPASS_RULES Bypass rules on work item updates
CHANGE_PROCESS Change process of team project.
Delete Delete team project
DELETE_TEST_RESULTS Delete test runs
EDIT_BUILD_STATUS Edit build quality
GENERIC_READ View project-level information
GENERIC_WRITE Edit project-level information
MANAGE_PROPERTIES Manage project properties
MANAGE_SYSTEM_PROPERTIES Manage system project properties
MANAGE_TEST_CONFIGURATIONS Manage test configurations
MANAGE_TEST_ENVIRONMENTS Manage test environments
PUBLISH_TEST_RESULTS Create test runs
RENAME Rename team project
START_BUILD Start a build
SUPPRESS_NOTIFICATIONS Suppress notifications for work item updates
UPDATE_BUILD Write to build operational store
UPDATE_VISIBILITY Update project visibility
VIEW_TEST_RESULTS View test runs
WORK_ITEM_DELETE Delete and restore work items
WORK_ITEM_MOVE Move work items out of this project
WORK_ITEM_PERMANENTLY_DELETE Permanently delete work items

ProjectAnalysisLanguageMetrics

Name Display name
Read View Project Analysis language metrics data
Write Write Project Analysis language metrics data

Proxy

Name Display name
Manage Manage proxies
Read Read proxies

Registry

Name Display name
Read Read registry entries
Write Write registry entries

Security

Name Display name
Read Read

Server

Name Display name
GenericRead View instance-level information
GenericWrite Edit instance-level information
Impersonate Make requests on behalf of others
TriggerEvent Trigger events

ServiceEndpoints

Name Display name
Administer Administer Endpoint
Create Create Endpoint
View View Endpoint
ViewAuthorization View Authorization

ServiceHooks

Name Display name
DeleteSubscriptions Delete Subscriptions
EditSubscriptions Edit Subscription
PublishEvents Publish Events
ViewSubscriptions View Subscriptions

ServicingOrchestration

Name Display name
Cancel Cancel Servicing Orchestration jobs
Queue Queue Servicing Orchestration jobs
Read View Servicing Orchestration information

SettingEntries

Name Display name
Read Retrieve setting entries
Write Write setting entries

Social

Name Display name
GenericRead View instance-level information
GenericWrite Edit instance-level information

StrongBox

Name Display name
AddItem Add Items to the StrongBox Drawer.
Administer Administer StrongBox Permissions.
AdministerDrawer Administer permissions for the StrongBox Drawer.
CreateDrawer Create a StrongBox Drawer.
DeleteDrawer Delete as StrongBox Drawer.
DeleteItem Delete Items from the StrongBox Drawer.
GetItem Retrieve Items from the StrongBox Drawer.

Tagging

Name Display name
Create Create tag definition
Delete Delete tag definition
Enumerate Enumerate tag definitions
Update Update tag definition

TestManagement

Name Display name
Read Read TestManagement

UtilizationPermissions

Name Display name
QueryUsageSummary Query Others' Usage

ViewActivityPaneSecurity

Name Display name
Read View only entities

WebPlatform

Name Display name
Read View web platform entities

WorkItemsHub

Name Display name
View View work items hub

WorkItemTracking

Name Display name
CrossProjectRead Cross Project Read Of WorkItemTracking Resources
Read Read WorkItemTracking
ReadHistoricalWorkItemResources (blank)
ReadRules Read rules only if permissions are avaliable
TrackWorkItemActivity Track work item read and write for a user

WorkItemTrackingConfiguration

Name Display name
Read View work item tracking configuration

VersionControl

VersionControlItems

Name Display name
AdminProjectRights Manage permissions
Checkin Check in
CheckinOther Check in other users' changes
Label Label
LabelOther Administer labels
Lock Lock
ManageBranch Manage branch
Merge Merge
PendChange Pend a change in a server workspace
Read Read
ReviseOther Revise other users' changes
UndoOther Undo other users' changes
UnlockOther Unlock other users' changes

VersionControlItems2

Name Display name
AdminProjectRights Manage permissions
Checkin Check in
CheckinOther Check in other users' changes
Label Label
LabelOther Administer labels
Lock Lock
ManageBranch Manage branch
Merge Merge
PendChange Pend a change in a server workspace
Read Read
ReviseOther Revise other users' changes
UndoOther Undo other users' changes
UnlockOther Unlock other users' changes

VersionControlPrivileges

Name Display name
AdminConfiguration Administer source control configurations
AdminConnections Administer source control connections
AdminShelvesets Administer shelved changes
AdminWorkspaces Administer workspaces
CreateWorkspace Create a workspace

Workspaces

Name Display name
Administer Administer the workspace
Checkin Check in changes to the workspace
Read View workspace information
Use Use the workspace

Git

Git Repositories

Name Display name
Administer Administer
CreateBranch Create branch
CreateRepository Create repository
CreateTag Create tag
DeleteRepository Delete repository
EditPolicies Edit policies
ForcePush Force push (rewrite history, delete branches and tags)
GenericContribute Contribute
GenericRead Read
ManageNote Manage notes
ManagePermissions Manage permissions
PolicyExempt Bypass policies when pushing
PullRequestBypassPolicy Bypass policies when completing pull requests
PullRequestContribute Contribute to pull requests
RemoveOthersLocks Remove others' locks
RenameRepository Rename repository

WorkItem

Plan

Name Display name
Delete Delete
Edit Edit
Manage Manage
View View

WorkItemQueryFolders

Name Display name
Contribute Contribute
Delete Delete
FullControl Full Control
ManagePermissions Manage permissions
Read Read
RecordQueryExecutionInfo Record query execution information

WorkItemTrackingAdministration

Name Display name
DestroyAttachments Destroy attachments
ManagePermissions Manage permissions

WorkItemTrackingProvision

Name Display name
Administer Administer
ManageLinkTypes Manage work item link types

Build

Build

Name Display name
AdministerBuildPermissions Administer build permissions
DeleteBuildDefinition Delete build definition
DeleteBuilds Delete builds
DestroyBuilds Destroy builds
EditBuildDefinition Edit build definition
EditBuildQuality Edit build quality
ManageBuildQualities Manage build qualities
ManageBuildQueue Manage build queue
OverrideBuildCheckInValidation Override check-in validation by build
QueueBuilds Queue builds
RetainIndefinitely Retain indefinitely
StopBuilds Stop builds
UpdateBuildInformation Update build information
ViewBuildDefinition View build definition
ViewBuilds View builds

BuildAdministration

Name Display name
AdministerBuildResourcePermissions Administer build resource permissions
ManageBuildResources Manage build resources
UseBuildResources Use build resources
ViewBuildResources View build resources

ReleaseManagement

ReleaseManagement

Name Display name
AdministerReleasePermissions Administer release permissions
CreateReleases Create releases
DeleteReleaseDefinition Delete release pipeline
DeleteReleaseEnvironment Delete release stage
DeleteReleases Delete releases
DeploymentSummaryAcrossProjects Deployment summary across projects
EditReleaseDefinition Edit release pipeline
EditReleaseEnvironment Edit release stage
ExportReleaseDefinition Export release definition
ManageDeployments Manage deployments
ManageReleaseApprovers Manage release approvers
ManageReleases Manage releases
ManageReleaseSettings Manage release settings
ManageTaskHubExtension Manage TaskHub Extension
ViewCDWorkflowEditor View CD work flow editor
ViewExternalArtifactCommitsAndWorkItems View external artifact commits and work items
ViewLegacyUI View legacy UI
ViewReleaseDefinition View release pipeline
ViewReleases View releases
ViewTaskEditor View task editor

LabExecution

TeamLabSecurity

Name Display name
Create Create
Delete Delete
DeleteLocation DeleteLocation
Edit Edit
ManageChildPermissions ManageChildPermissions
ManageLocation ManageLocation
ManagePermissions ManagePermissions
ManageSnapshots ManageSnapshots
ManageTestMachines ManageTestMachines
Pause Pause
Read Read
Start Start
Stop Stop
Write Write

Discussion

Discussion Threads

Name Display name
Administer Manage discussion permissions
GenericContribute Contribute to discussions
GenericRead View discussions
Moderate Moderate discussions

DistributedTask

DistributedTask

Name Display name
AdministerPermissions Administer Permissions
Create Create
Listen Listen
Manage Manage
Use Use
View View

Environment

Name Display name
Administer Administer Permissions
Create Create
Manage Manage
Use Use
View View

Library

Name Display name
Administer Administer library item
Create Create library item
Use Use library item
View View library item
ViewSecrets View library item secrets

MetaTask

Name Display name
Administer Administer task group permissions
Delete Delete task group
Edit Edit task group

Integration

CSS

Name Display name
CREATE_CHILDREN Create child nodes
Delete Delete this node
GENERIC_READ View permissions for this node
GENERIC_WRITE Edit this node
MANAGE_TEST_PLANS Manage test plans
MANAGE_TEST_SUITES Manage test suites
WORK_ITEM_READ View work items in this node
WORK_ITEM_WRITE Edit work items in this node

Iteration

Name Display name
CREATE_CHILDREN Create child nodes
Delete Delete this node
GENERIC_READ View permissions for this node
GENERIC_WRITE Edit this node

Chat

Chat

Name Display name
AddRemoveChatRoomMember Add/Remove Chat Room Member
CloseChatRoom Close Chat Room
CreateChatRoom Create Chat Room
DeleteChatRoom Delete Chat Room
DeleteChatRoomMessage Delete Chat Room Message
ManageChatPermissions Manage Chat Permissions
ReadChatRoomMessage Read Chat Room Message
ReadChatRoomMetadata Read Chat Room Metadata
ReadChatRoomTranscript Read Chat Room Transcript
UpdateChatRoomMessage Update Chat Room Message
UpdateChatRoomMetadata Update Chat Room Metadata
WriteChatRoomMessage Write Chat Room Message

検証用の Windows ベース イメージを Compact OS にして約 30 % (1.6 GB) ディスク節約する話

Compact OS とは何なのか

マイクロソフトは、パートナーを通じて戦略的に Windows タブレット PC を複数出していますが、タブレットのような小型端末では、SSD などの大容量ディスクが搭載できないため Windows のようなディスクの占有率の大きい OS をインストールするとユーザー使用領域がほとんどないという問題が発生します。そこで、Windows 10 では特定条件を満たすと自動的に Compact OS と呼ばれる OS のシステム ファイルを圧縮するモードでインストールされるようになっています。また、条件を満たしていなくても OEM がマスターイメージ作成時にオプションを有効にすることもできます。compact.exe というコマンドを使うことであとから圧縮/非圧縮を変更できますが、今回はこの話はせずに、インストール時に Compact OS 化する話をします。なお、Compact OS というのは、ファイルアクセス時に展開することになるため、パフォーマンスが悪い HDD などのディスクでは推奨されません。

なぜ Compact OS なのか

私は Vagrant + VMWare を使って検証 VM を管理していますがベース イメージ自体を小さくするということは、ディスク使用量の減少だけでなく、BOX ダウンロード時間の短縮、BOX 管理用クラウド ドライブの使用料削減、など様々なメリットがあるからです。

Compact OS のインストール方法

Windows 10 のインストール画面で Shift+F10 を押し、コマンド プロンプトを起動します。

(オプション) 英語キーボードを使用している場合

英語キーボードを使用している場合、日本語版の OS では日本語配列のキーボードであることが想定されているため、うまく入力ができません。 英語のキーボードのリストを取得する場合、次のように入力します。

wpeutil ListKeyboardLayouts 0x411

表示されたリストの中から使用中のキーボードを選択します。たとえば英語 "(インターナショナル)" キーボードの場合は次のように実行します。

wpeuitl SetKeyboardLayout 0411:00020409

変更後、次のようにして新しくコマンド プロンプトを起動すれば、英語配列でキー入力ができるようになります。

start cmd

パーティションを設定する

パーティションは diskpart コマンドで行います。コマンドライン上で以下のコマンドを実行し、対話モードでパーティションを作成していきます。

diskpart

パーティションの作成方法は、マイクロソフトの以下のドキュメントを参考にします。

https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn898510(v=vs.85).aspx

具体的には、以下のコマンドで UEFI/GPT ベースのハード ドライブ パーティションを設定していきます。なお、私の場合、回復パーティションのほうはディスク サイズ削減を目的に作成していません *1

select disk 0
clean
convert gpt
create partition efi size=100
format quick fs=fat32 label="System"
assign letter="S"
create partition msr size=16
create partition primary 
shrink minimum=500
format quick fs=ntfs label="Windows"
assign letter="W"

create partition primary
format quick fs=ntfs label="Recovery tools"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001

list volume
exit

コンパクト OS イメージを適用する

必須ではありませんが、作業を高速化するために電源プランを "高パフォーマンス" に変更します。

powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c

以下のコマンドで、ISO に含まれるエディションを取得します。

dism /get-ImageInfo /ImageFile:D:\sources\install.wim

表示されたリストから、インストールするエディションをのインデックス番号を特定します。 たとえば、"Windows 10 1803 (Business Edition)" の場合、以下のリストが表示されます。

# 名前
1 Windows 10 Education
2 Windows 10 Enterprise
3 Windows 10 Pro
4 Windows 10 Pro Education
5 Windows 10 Pro for Workstations

次にコンパクト OS イメージを W:\ に適用します。以下の例では、"Windows 10 Enterprise" (2) をインストールの対象にしています。

dism /Apply-Image /ImageFile:D:\sources\install.wim /Index:2 /ApplyDir:W:\ /compact

BCDBoot を使ってシステム パーティションを構成します。

W:\Windows\System32\bcdboot W:\Windows /s S:

システムを再起動します。

wpeutil reboot

再起動後、Windows が "準備しています" と言いながら様々な設定をしますので、しばらく待ちます。 (結構長いです)

準備が完了するとコルタナが話しかけてきますので、あとは通常のセットアップ同様に作業を行います。

Compact OS になっているかどうかを確認する

Compact OS としてインストールできているかどうかを確認するには次のコマンドを実行します。

compact /compactos

Compact OS になっていれば、以下のように表示されます。

システムは圧縮状態です。管理者が変更しない限り、この状態のままになります。

それでは、よい Compact OS 生活を。Enjoy!

*1:検証用の VM を大切に使う方は回復パーティションを用意したほうがいいと思います。私は壊れたら作り直す精神です。

空白の変更を無視して本当に変更されたファイルだけを git add する方法

社内的には Git リポジトリとしてコード管理しているが、お客様には git リポジトリをそのまま渡したくないので export したものをご提供。後日、お客様から改修依頼があって、現状のコードを送って git status したら大量の変更が!...しかし、git diff すると空白が違うだけのファイルばかり...というときに本当に変更されたファイルだけを git add したい、そういう話です。

この問題は、以下のコマンドで解決できます。

git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -

alias として登録して登録する場合は以下のコマンドを実行します。

ユーザー単位で設定するなら --global、システム単位で設定するなら --system オプションをつけてください。

git config alias.addnw=!sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero -

参考

参考というか、ここの回答をそのまま書いたようなものなんですが...備忘録を兼ねて書きました。

では、よい git add 生活を。Enjoy!

.NET Compiler Platform (aka "Roslyn") を使う場合に必要なコンポーネント群

以下のコンポーネントをインストールします。

コンポーネント ID 名前 説明
Microsoft.VisualStudio.Workload.CoreEditor Visual Studio のコア エディター 構文認識コード編集機能、ソース コード管理、作業項目管理などの Visual Studio の基本的なシェル エクスペリエンス。
Microsoft.VisualStudio.Workload.VisualStudioExtension Visual Studio 拡張機能の開発 Visual Studio 用のアドオンや拡張機能 (新しいコマンド、コード アナライザー、ツール ウィンドウを含む) を作成します。
Microsoft.Component.CodeAnalysis.SDK .NET Compiler Platform SDK .NET Compiler Platform SDK

なお、検証用のプロジェクトを作成する目的で、以下のプロジェクトも入れておくといいと思います (この辺りはお好みで)。

コンポーネント ID 名前 説明
Microsoft.VisualStudio.Workload.ManagedDesktop .NET デスクトップ開発 説明: C#、Visual Basic、F# を使用して、WPF、Windows フォーム、コンソール アプリケーションをビルドします。

私は以下も一緒にいれています (T4 いいですよね)。

コンポーネント ID 名前 説明
Microsoft.VisualStudio.Component.TextTemplating テキスト テンプレート変換 テキスト テンプレート変換 (T4)

それでは、よい Roslyn 生活を。Enjoy!

Vagrant Provision を Chocolatey で快適にした話

以前に Vagrant up するときに Visual Studio を自動インストールする方法を書きましたが、ほかのツールもいろいろとインストールしたいですよね。

Windows のアプリケーションは基本的にサイレント インストールする設計になっていないアプリも多いので、いろいろと面倒なのですが、apt-get install と同じぐらいの手軽さで Windows アプリもインストールさせてよ!と思う人は多いようで、ちゃんとプロジェクトがあります。名前は、"Chocolatey" です。

たぶん .NET 開発者なら知らない人はいないであろう NuGet と呼ばれる技術をバックエンドにつかったもので、choco install でアプリケーションを手軽にインストールできます。

実際のところ、ホスト マシンですら Chocolatey で構築してしまおうという人も多いのですが、サイレント インストールなので細かい設定ができなかったりして、私はあまりホストのセットアップに使うのは好きではありません。 一方、1 日 1 回以上作成する可能性すらある検証マシンの場合、とにかく入ってくれればいいというシチュエーションは少なくなく、Chocolatey との相性は抜群と言えます。

Chocolatey をインストールする

Chocolatey を使うためには、まずは Chocolatey をインストールしなければなりません。 ワンライナーで手軽にインストールできるようにしてくれているので、ありがたくその方法を使います。

インストール方法は以下に記載があります。

https://chocolatey.org/install

Vagrant において Provisioner の 1 つである shell は Windows においては PowerShell を呼び出すよ、と書かれているので Install with Powershell.exe のほうを使いましょう。

具体的には以下のように Vagrantfile を記載します (必要に応じて設定などを追加してください)。

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Install Chocolatey inline script
$script = <<SCRIPT
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = "<your box>"
    config.vm.provision "shell", inline: $script
end

なお、config.vm.provison は複数書けます。複数書いた場合は上から順番に実行されるようです。

Chocolatey でアプリを自動インストールする

Chocolatey でアプリをインストールするには、上記の SCRIPT に追記してもいいですし、次のように PowerShell を呼び出して手動でインストールしてもいいです。 同じ環境を何度も作る必要があるなら SCRIPT に追記したほうがいいですし、一時的にアプリをインストールしたいなら Powershell 経由でもいいですね。

たとえば、Git をインストールする場合は、以下のように実行すれば勝手にインストールしてくれます。

choco install git -y

ポイントは、最後の -y でこれをつけないと "インストールしますか?(Y/N)" な対話型な状態になってしまうので、自動的に Y (Yes) になるよう -y をつけます。 特に Vagrantfile に記載した場合は、インストールに失敗してしまうのでご注意を。

それでは、よい Chocolatey 生活を。Enjoy!