PoshCode Archive  Check-in [30d3d1a83a]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Small script to strongly syncronyze folder with ‘original’.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:30d3d1a83a2ae7ad5959182c463e2854de1c8948093d258fe854210f52133199
User & Date: M Skourlatov 2018-06-10 14:22:15
Context
2018-06-10
14:22
ISE profile code for doing module development check-in: bb2f3cefb1 user: jrich523 tags: trunk
14:22
Small script to strongly syncronyze folder with ‘original’. check-in: 30d3d1a83a user: M Skourlatov tags: trunk
14:22
Provide a begin and end time frame (mm dd yyyy) and this will calculate the years, months and days between the two dates. This is NOT 100% accurate but it was close enough for what I was trying to do. Someone with better math skills should be able to improve the accuracy. check-in: 597f1652f7 user: Dan In Philly tags: trunk
Changes

Added Start-FolderSync.ps1.



































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# encoding: ascii
# api: powershell
# title: Start-FolderSync
# description: Small script to strongly syncronyze folder with ‘original’.
# version: 0.1
# type: class
# author: M Skourlatov
# license: CC0
# function: Start-FolderSync
# x-poshcode-id: 6890
# x-archived: 2017-05-13T18:16:33
# x-published: 2017-05-09T23:46:00
#
#
Add-Type -TypeDefinition @"

public struct HashContainer : System.IComparable
{
	public ulong High;
	public ulong Low;

	public HashContainer(byte[] Buffer)
	{
		System.Array.Reverse(Buffer);
		this.Low = System.BitConverter.ToUInt64(Buffer, 0);
		this.High = System.BitConverter.ToUInt64(Buffer, 8);
	}

	public int CompareTo(object obj)
	{
		if (obj == null) { return 1; }
		var other = (HashContainer)obj;

		int compare = this.High.CompareTo(other.High);
		if (compare != 0) return compare;
		return this.Low.CompareTo(other.Low);
	}

	public override string ToString()
	{
		return string.Format("{0:X}{1:X}", this.High, this.Low);
	}

}

public class FIComparable : System.IComparable
{
	public System.IO.FileInfo Info;

	private bool hasHash;
	private HashContainer hash;

	public FIComparable(System.IO.FileInfo info)
	{
		this.Info = info;
		this.hasHash = false;
	}

	public HashContainer GetHash()
	{
		if (this.hasHash) { return this.hash; }

		var crypto = new System.Security.Cryptography.MD5CryptoServiceProvider();
		var stream = new System.IO.FileStream(
			this.Info.FullName,
			System.IO.FileMode.Open,
			System.IO.FileAccess.Read,
			System.IO.FileShare.None);
		var buf = crypto.ComputeHash(stream);
		stream.Close();

		this.hash = new HashContainer(buf);
		this.hasHash = true;
		return this.hash;
	}

	public int CompareTo(object obj)
	{
		if (obj == null) { return 1; }
		var other = obj as FIComparable;

		if (null != other)
		{
			int compare = this.Info.Name.CompareTo(other.Info.Name);
			if (compare != 0) { return compare; }
			compare = this.Info.Length.CompareTo(other.Info.Length);
			if (compare != 0) { return compare; }
			return this.GetHash().CompareTo(other.GetHash());
		}
		else { throw new System.ArgumentException(); }
	}
	
	public override string ToString() { return this.Info.Name; }
}
"@

Function Start-FolderSync
{
	Param
	(
		[parameter(Mandatory, Position = 0)]
		[ValidateScript({ Test-Path -Path $_ -PathType 'Container' })]
		[string]$Reference,
		[parameter(Mandatory, Position = 1)]
		[string]$Synchronized
	)

	function Get-Comparable($list)
	{
		$sync = New-Object 'System.Collections.Generic.List[FIComparable]'
		foreach ($item in $list) { $sync.Add((New-Object FIComparable $item)) }
		return $sync
	}

	$gotcha = Get-ChildItem -LiteralPath $Reference
	$fileList = New-Object 'System.Collections.Generic.List[System.IO.FileInfo]'
	$copyList = New-Object 'System.Collections.Generic.List[System.IO.FileInfo]'
	$dirList = New-Object 'System.Collections.Generic.List[System.IO.DirectoryInfo]'
	# [System.IO.FileAttributes]::Directory -eq 16

	foreach ($item in $gotcha)
	{
		if (($item.Attributes -band 16) -eq 16)
			{ $dirList.Add($item) }
		else
			{ $fileList.Add($item) }
	}

	$ref = Get-Comparable $fileList

	$syncDir = [System.IO.Directory]::CreateDirectory($Synchronized)
	if ($syncDir -eq $null) { return $false }

	$syncFileList = Get-ChildItem -LiteralPath $syncDir.FullName -File
	$sync = Get-Comparable $syncFileList
	if ($sync -eq $null -or $ref -eq $null)
	{
		$copyList = $fileList
	}
	else
	{
		$compasion = Compare-Object -ReferenceObject $ref -DifferenceObject $sync
		foreach ($item in $compasion)
		{
			if ($item.SideIndicator -eq '<=')
			{
				$copyList.Add($item.InputObject.Info)
			}
		}
	}

	foreach ($item in $dirList)
	{
		Start-FolderSync -Reference $item.FullName -Synchronized $($syncDir.FullName + '\' + $item.Name)
	}
	
	foreach ($item in $copyList)
	{
		Copy-Item -Path $item.FullName -Destination $syncDir.FullName -Verbose
	}
}