読者です 読者をやめる 読者になる 読者になる

きょう

短期的に何度も開いたり、あとでちゃんと読もうと思ったWebページはデスクトップにショートカットとして置いてる。ブラウザアイコンにページのタイトルが付いて画面の上で好きなように配置できるから安心する。IEのころは右クリックでメニューがあったし、chromeはアドレス欄をドラッグアンドドロップで置ける。定期的に全部捨てる。あるときのデスクトップにあるショートカットを記録しておけば後で見たときに雰囲気を思い出したりできそう。

右クリックの「送る」メニューでWebページショートカットのリストを作るスクリプトを書いてみた。

function f {
    param([IO.FileInfo]$fi)

    $1, $2 = (Get-Content $fi -TotalCount 2)
    if ($2 -ne $null -and $1 -eq '[InternetShortcut]'){
        [IO.Path]::GetFileNameWithoutExtension($fi.Name)
        $2.Substring(4)
        $fi.LastWriteTime
    }
}

$OutputEncoding = [Console]::OutputEncoding
$args | 
    Get-ItemProperty | 
    Sort LastWriteTime | 
    % { ,(f $_) } | 
    % {"*  {2:yyyy/MM/dd hh:mm} [{0}]({1})" -f @($_)} |
    Clip 

SendToフォルダにC:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File script.ps1のショートカットファイルを置く

今日のデスクトップ

windowsの再インストールをした

デスクトップ環境は定期的にさらの状態にしてる。継ぎ足しで環境を作っていると再現が難しくなってトラブルに弱くなる。いままでのやり方を見直すきっかけにもなる。

NUC6i7KYK、windows10 pro

Windowsのインストール microsoftのサイトからポチポチしたらusbメモリに準備ができる。これでAnniversary Update適用済みでインストールされる。 ディスクのデータを全部消すことから始めたいから、シャットダウンをして用意したusbメモリから起動する。Windowsの中からSetupを実行するとwindows.old的なフォルダが残って潔くない。 ディスクユーティリティ的なウィンドウが出るからパーティションを削除するところからスタートする。

ドライバのインストール

www.intel.co.jp

Windowsの機能の有効化

今回は無し

Windows update

更新プログラムのチェックをして出なくなるまで

キーボードのキーの置き換え

HHKB Lite2 英語配列モデルを使ってる。DIPスイッチでDeleteキーをBSキーとして使ってる。

右winキーを右controlキーにする。レジストリにキーを追加する。

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,e0,5c,e0,00,00,00,00

エクスプローラ

user shell folders

「デスクトップ」以外の「ビデオ」とか「検索」とかのフォルダ(user shell folderというらしい)は使わなくて邪魔。使わないあて先の場所に同じ場所を指定するとエクスプローラーで表示されなくなる。間違えて使いたいフォルダーを消してしまったらレジストリでパスを直せばよい。

右クリックの送るメニューを減らす

エクスプローラーのアドレス欄でsendToでフォルダに移動できる。使わないリンクを削除。

右クリックの新規作成を減らす

windows10 右クリック 新規作成 - Google 検索

アプリのアンインストール

簡単にアンインストールできそうにないものはあきらめる。

環境変数 HOME

HOMEを%userprofile%で作っておくおまじない。

init.cmd

mattn.kaoriya.net

アプリケーションのインストール

  • chrome
  • 7zip
  • corvusskk
  • git for win
  • python
    • pip install awscli

C#でPDFに画像とテキストを差し込むには

テンプレートとして作ってあるPDFに後で画像とテキストを差し込んで新しいPDFファイルを作るとしたら。 Qiitaにそのまんまの記事があった。 iTextSharpというものがあるらしい。 google翻訳によると、iTextSharpは使い方によっては有償ですと書いてあるように読める。あとAGPLライセンスであるとも書いてあった。 手元でちゃちゃと使うならこれでいいけど、サービスで使うならお金払うか、やりたいことはPDFじゃなくていいんじゃないかってところから考えなきゃな。

qiita.com

github.com

nokoshitamono.blogspot.jp

AWS EC2のWindowsインスタンスを作業用として利用するにあたり固定の名前で接続できるようする方法を考えてみた

AWS EC2のWindowsインスタンスを使って何かするとき簡単にインスタンスを立ち上げてWinRMで接続できるようにする。CloudFormationでEC2インスタンスを起動してRoute53にパブリックIPを登録する。

  • 送信元のIPアドレスで接続を制限をする(セキュリティグループを利用)
  • そのときで最新のAmazon AMIを使う
  • パブリックIPをRoute53に登録して名前で接続できるようにする

あらかじめ用意しておく

  • VPCとサブネット
  • セキュリティグループ
  • IAMロール
  • Route53 HostedZone*1
AMIの検索
aws ec2 describe-images 
    --owners amazon 
    --filter Name=name,Values="Windows?Server?2012?R2*Japanese*Base*"

ワイルドカード?*が使える。case sensitive

Windowsの設定

EC2インスタンス起動時にUserDataで設定する

Get-NetFirewallPortFilter -Protocol tcp | 
    ?{ $_.LocalPort -eq 5985 } | 
    get-netfirewallrule | 
    Get-NetFirewallAddressFilter | 
    Set-NetFirewallAddressFilter -RemoteAddress Any

Amazon AMIはWinRM(Windows リモート管理 )がファイアウォールでの許可を含めて有効化されている*2。ただし、ローカルサブネットに限定された許可のため変更する必要がある。ここではVPCのセキュリティグループによって接続元IPを制限するのでWindowsファイアウォールではすべて許可とする。

接続元ではWinRMを有効化してTrustedHostsに今回使用するホスト名を追加する*3

スタックの更新

パブリックIPはインスタンスの「停止」「開始」で変わる。スタックリソースのレコードセットをCloudFormationの外で変更すると以後のスタックの更新、削除が失敗する。スタックを削除したらEC2インスタンスとレコードセットがひとセットとして削除されて欲しい。スタックの更新によってレコードセットの値を変更する。

$params = (Get-CFNStack -StackName $stackname).Parameters 
$params | % {$_.UsePreviousValue = $TRUE; $_.Value = $NULL}
$p = $params | ? key -eq "publicIp" 
$p.UsePreviousValue = $FALSE
$p.Value = $ip

Update-CFNStack
    -StackName $stackname
    -Parameters $params
    -UsePreviousTemplate $true
    -Capability "CAPABILITY_IAM"

テンプレートを変更するかパラメータの値を変更しないとCloudFormationは変更があったことを検知しない。ここではEC2インスタンスリソースを変更せずにレコードセットリソースのみを更新したい。レコードセットの値はパラメーターとして指定できるテンプレートとする。

スタックの更新に必要なIAMポリシー

テンプレートの書き方によって変わる。スタックリソースに対しては更新するリソースについてのものだけ許可されていればいい。この場合ではテンプレートにEC2インスタンスリソースが含まれていれも更新されるリソースがレコードセットリソースのみなのでEC2インスタンスに関わる許可は不要。ただし、テンプレートにパラメータの型としてAWS::EC2::Image::IdやAWS::EC2::Subnet::Idなどを指定していると参照するためのIAMポリシーが必要になる。

レコードセットの更新に必要なIAMポリシー

"Effect": "Allow",
"Action": [
    "route53:ListHostedZones"
],
"Resource": [
    "arn:aws:route53:::hostedzone"
]
"Effect": "Allow",
"Action": [
    "route53:GetChange",
    "route53:ChangeResourceRecordSets"
],
"Resource": [
    "arn:aws:route53:::hostedzone/[Hostedzone ID]"
]

スタックの更新に必要なIAMポリシー

"Effect": "Allow",
"Action": [
    "cloudformation:DescribeStacks",
    "cloudformation:UpdateStack"
],
"Resource": [
    "arn:aws:cloudformation:ap-northeast-1:[account ID]:stack/[stack name]/*"
]
スタートアップ時のタスク実行

タスクスケジューラを使ってWindows起動時にスタックの更新を実行する。PowerShellスクリプトをタスクスケジューラに登録するにはPSScheduledJobモジュールを使う。スタートアップ時に実行させるにはさらに追加の設定をしないとエラーによりタスクの実行が失敗する。

タスク スケジューラは、ユーザー "<コンピューター名>\Administrator" の "\Microsoft\Windows\PowerShell\ScheduledJobs\<タスク名>" タスクを開始できませんでした。追加データ: エラー値: 2147943711。*4

LocalSystemアカウントで実行させると成功する。

Register-ScheduledJob
    -ScriptBlock $sb
    -Name $name
    -Trigger @{Frequency = "AtStartup"}

Get-ScheduledTask -TaskName $name | 
    Set-ScheduledTask -User "NT AUTHORITY\SYSTEM"

*1:今回はあらかじめ用意したHostedZoneにCloudFormationでレコードセットを追加する方法にしたが、スタックごとにHostedZoneを追加する方法にすればもうすこし簡単になりそうではある。ちなみに、HostedZoneは1つずつの料金(月額のホストゾーン料)がかかるが追加から12時間以内に消せばタダ。

*2:http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/windows-ami-version-history.html#ami-image-changes

*3:WinRm TrustedHosts 追加

*4:タスクスケジューラのログは有効にしないと見られない。

きょうまで

aws cloudformation
windows server 2012 R2

cfn-initのcommandsで時間がかかる。一つずつコマンド終了後にデフォルトで60秒の待機時間がある。waitAfterCompletionで0に設定できる。
AWS::CloudFormation::Init - AWS CloudFormation
再起動を待ってcfn-initを続ける場合は、foreverを指定する。

cfn-initのcommandsの実行時に日本語の出力があるとUnicodeEncodeErrorで失敗する。とりあえず、コマンドの出力をリダイレクトして回避
sqlcmd -i file.sql > nil
UserDataのscriptタグではエラーは出ない。ただしログの日本語部分は文字化け。
*1 *2

EBSをアッタチしてもwindowsではボリュームがoffline
get-disk | ? isoffline | set-disk -isoffline $false

EBSをデタッチするときに必要なwindowsのボリュームの探し方
Windows EC2 インスタンスのボリュームへのディスクのマッピング - Amazon Elastic Compute Cloud
(get-volume $driveLetter | Get-Partition | get-disk).Location
MSFT_Disk class (Windows)
Hard Disk Location Path Format

YAMLでテンプレート
関数は!で書けるけど連続して書けない場合がある
Fn::Base64: !Sub
!Select[!Ref Value, [1,2,3]]

属性はGetAttとピリオドで取得
!GetAtt ResourceName.attribute

Fn::GetAZs: region
regionを空にした場合はAWS::Regionの値
リージョンにあるすべてのazからアカウントが使用できるazが決められているので、見えるazはアカウントごとに違う。

cfn-init windowsの場合
設定キーの実行順序
package, sources, file, commands, services

*1:レジストリでcmdの文字コードを変更してしまっても解決できるかも。試してない

*2:新しいwindowsでならcmdの文字コードがよくなってるらしいのでまた違った対応ができるかも。試してない

今日

WinRM:Windowsリモート管理

EC2でwindowsを扱う。 AMIは名前で検索して日付が最新のものを使う。
Windows_Server-2012-R2_RTM-Japanese-64Bit-Base

amazon AMIで用意されていることの一覧 イメージの変更点

WinRMは構成済み。構成済みのファイアウォールではローカルサブネットからの受信のみが許可されている。インスタンスファイアウォールでは制限をせずに、セキュリティグループで許可するIPアドレスを指定することにする。

ちなみに、LocalAccountTokenFilterPolicy(リモートUAC)は1(無効)に設定されている。ドメイン環境でなくてもリモートから管理者権限で操作ができる。 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system

アカウント名とパスワードでリモートにログインすることになるので、送信側のTrustedHostに送信先を登録する必要がある。ホスト名でもIPアドレスでも*(ワイルドカード)でも可。
winrm set winrm/config/client @{TrustedHosts="Server0"}
既にある値に追記するならpowershell
Set-Item wsman:\localhost\Client\TrustedHosts Server0 -Concatenate -Force

これから

  • WinRM HTTPSトランスポートの構成と-useSSL
  • DSCとWebPIを使って最新AMIからWebサーバーを用意する手順
  • Route53へのパブリックIPの登録の自動化
  • Route53のプライベートホストゾーンを使ってサーバー間を固定の名前で接続する

いま

とりあえずこんな感じでできた。呼ばれるまで接続したまま待つハンドラー。

  • staticフィールドでTaskCompletionSourceとGUIDのリストを持つ。
  • リクエストがきたらGUIDとTaskCompletionSourceを作ってリストに追加して待機。
    • 別のリクエストでGUIDを指定してリストからTaskCompletionSourceをSetResultする。
  • 再開されてレスポンスが返る。

gist3d97435824e4a04761dfe04612aca9b4