世代を重ねるにつれ徐々に不具合が解消されていきつつはあるDFSR。
PSで設定できそうって書いてあるのでやってみる。
$dn="abc.dom"
$gn="testg1"
$fn="testf1"
$sv1="server1"
$sv2="server2"
$sv1_dir="e:\dir\test1"
$sv2_dir="e:\dir\test1"
$r = New-DfsReplicationGroup -DomainName $dn -GroupName $gn
$r | New-DfsReplicatedFolder -DomainName $dn -FolderName $fn
$r | Add-DfsrMember -DomainName $dn -ComputerName $sv1,$sv2
$r | Add-DfsrConnection -DomainName $dn -SourceComputerName $sv1 -DestinationComputerName $sv2
$r | Get-DfsrConnection -DomainName $dn | Set-DfsrConnection -DomainName $dn -DisableRDC $True -DisableCrossFileRDC $True
$r | Get-DfsrMembership -DomainName $dn -ComputerName $sv1 |Set-DfsrMembership -DomainName $dn -ContentPath $sv1_dir -DisableMembership $true -force
$r | Get-DfsrMembership -DomainName $dn -ComputerName $sv2 |Set-DfsrMembership -DomainName $dn -ContentPath $sv2_dir -DisableMembership $true -force
$r | Get-DfsrMembership -DomainName $dn -ComputerName $sv1 |Set-DfsrMembership -DomainName $dn -PrimaryMember $true -force
$r | Get-DfsrMembership -DomainName $dn | Set-DfsrMembership -DomainName $dn -MinimumFileStagingSize Size512TB -StagingPathQuotaInMB 10 -RemoveDeletedFiles $true -Force
$r | Get-DfsrMembership -DomainName $dn | Set-DfsrMembership -DomainName $dn -DisableMembership $false -Force
えーとすでに割と冗長というか、コマンド分ける必要あるのこれ?
これ2サーバにゃのでわかりやすいけど4サーバメッシュとか絶対やりたくにゃい。
ま、それはともかく、ここまで設定してうまくいきそうに見えるが、よく見るとRemoveDeletedFilesがfalseのままににゃってる。これいろいろやっても全然反映されにゃいというかGUIから変更してもGet-DfsrMembershipに反映されてにゃいのでもう根本的に実装がバグってるとしか。
で、DfsrAdminにゃら通るんだよにゃ
DfsrAdmin.exe membership set /MoveDelFiles:false /rgname:$gn /rfname:$fn /memname:$sv1
DfsrAdmin.exe membership set /MoveDelFiles:false /rgname:$gn /rfname:$fn /memname:$sv2
2012r2でいろいろ改善されてるとか書いてあるが、全体のクオリティがこのくらいってのがまたMSらしいというかほんと駄目。
未だお世話ににゃるcmd.exe・・・これまでsleepにはpingを使っていたのだが、Win7くらいからはwaitforでよさそう。
waitfor xxx /t 60
で60秒待つ。xxxはダミーにゃので乱数にゃんかにした方が良いね。
例えば
waitfor %random%%random%%random%%random%%random%%random% /t 60
とかだろうか。
で、waitfor自体は本来シグナルを待つ機能であって、これはこれで何かに使えそうではある。
例えば
waitfor xxx & @echo copy done
しといて
copy a b & waitfor /si xxx
すると複数bat間で完了待ちとか出来る。
ただ標準だとこれLANに垂れ流しちゃうので、localhostに留めておくにゃら
waitfor /si xxx /s \\%COMPUTERNAME%
で送信ね。
Hyper-Vのレプリケーションは、PSからだと
Enable-VMReplication -VMName $vmname -ReplicaServerName $server -ReplicaServerPort 80 -AuthenticationType Kerberos -VSSSnapshotFrequencyHour 1 -RecoveryHistory 24 -ReplicationFrequencySec 30
Start-VMInitialReplication -VMName $vmname
みたいにゃので行けるが、この状態ではいくつか問題も残る。
まず受け側サーバに生成されるレプリカvmが、見た目で判別できにゃい。GUIがしょぼいだけとも言えるが、vm名等で区別しにゃいとどこの鯖にあるvmのレプリカで、どこのストレージ上にあるのかとかが大変分かりづらい。というか同名vmとか作ってしまうとスクリプト内で判別ルーチン走らせにゃければにゃらにゃい。運用上絶対避けたい事態だがEnable-VMReplicationでvm名指定できにゃいんだよねー
そんにゃわけでまずレプリカ名を変更すると良い。vm名やvmの格納場所を変更してもreplicationは問題にゃく動作する。
次に、このレプリカは受け側サーバのDefaultStorageLocation以下に格納されてしまうので使い勝手が悪い。このStorageLocationは送信側サーバ毎に指定したりも出来るが、普通に考えてやりたいのはvm毎に指定のPathにレプリカを置きたいわけで、そうすると手法としては、
Enable-VMReplication後に
Move-VMStorage -DestinationStoragePath してから
Start-VMInitialReplication -VMName $vmname
ということににゃる。これにゃらxml程度しか生成されてにゃいので瞬時に処理が終わる。
よって纏めると、
$vmname = "vm1"
$vmname_rep = "vm1_replica"
$dst_server = "sv2"
$dst_path = "\\sv2\share\vm1_rep"
$VM_src = get-vm | ?{ $_.Name -eq $vmname }
$VM_src | Enable-VMReplication -ReplicaServerName $dst_server -ReplicaServerPort 80 -AuthenticationType Kerberos -VSSSnapshotFrequencyHour 1 -RecoveryHistory 24 -ReplicationFrequencySec 30
$VM_dst = get-vm -ComputerName $dst_server -Id $VM_src.Id
$VM_dst | Set-VM -NewVMName $vmname_rep
$VM_dst | Move-VMStorage -DestinationStoragePath $dst_path
$VM_src | Start-VMInitialReplication
といった手順ににゃる。
Win鯖にストレージがついてるんだが、別のPCからそこへ大型ファイル書き込んだら、鯖のメモリをガンガン食って、スワップしまくってvm落ちてRDP落ちて応答にゃくにゃったんだが、コピー止めたら復帰した。
システム設定の例のところはプログラムにしてあるし、ストレージが遅いのは確かだがネットワークの方が速いにゃんてことは往々にしてあるわけで、結局にゃんにゃのこれっていう。