· 8 years ago · Jun 16, 2018, 07:58 AM
1$scriptPath = Split-Path -Parent $PSCommandPath
2Class settings{
3 [string]$AdGroup
4 [string]$MachineFilter
5 [string]$Source1
6 [string]$Destination1
7 [string]$Source2
8 [string]$Destination2
9}
10$settings = [settings]::new()
11if(Test-Path $scriptPath\settings.xml){
12 $settings = Import-Clixml -Path $scriptPath\settings.xml
13}
14else{
15 $settings | Export-Clixml -Path $scriptPath\settings.xml
16}
17
18#Install Invoke-Parallel if not installed
19if(){
20 Install-Module PSParallel
21 Import-Module PSParallel
22}
23
24#Install PSSQLite for in memory database
25if(){
26 Install-Module PSSQLite
27 Import-Module PSSQLite
28}
29
30$SourceFolder = ""
31$DestinationFolder = ""
32
33$hklm = 2147483650
34$hku = 2147483651
35$profileListKey = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
36$mediaPlayerKey = "SOFTWARE\Microsoft\MediaPlayer\Preferences"
37
38Add-Type -AssemblyName System.Windows.Forms
39[System.Windows.Forms.Application]::EnableVisualStyles()
40
41#region begin GUI{
42$AnchorLeftRight = ([System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right -bor [System.Windows.Forms.AnchorStyles]::Top)
43$AnchorLeftRightBottom = ([System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right -bor [System.Windows.Forms.AnchorStyles]::Bottom)
44$AnchorRightBottom = ([System.Windows.Forms.AnchorStyles]::Right -bor [System.Windows.Forms.AnchorStyles]::Bottom)
45$AnchorAll = ([System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right -bor [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom)
46$FileDeployForm = New-Object system.Windows.Forms.Form
47$FileDeployForm.ClientSize = '400,559'
48$FileDeployForm.text = "File Deploy"
49$FileDeployForm.TopMost = $false
50
51$SettingsGroupbox = New-Object system.Windows.Forms.Groupbox
52$SettingsGroupbox.height = 195
53$SettingsGroupbox.width = 366
54$SettingsGroupbox.text = "Settings"
55$SettingsGroupbox.Anchor = $AnchorLeftRight
56$SettingsGroupbox.location = New-Object System.Drawing.Point(16,14)
57
58$ADGroupTextBox = New-Object system.Windows.Forms.TextBox
59$ADGroupTextBox.multiline = $false
60$ADGroupTextBox.width = 215
61$ADGroupTextBox.height = 18
62$ADGroupTextBox.Anchor = $AnchorLeftRight
63$ADGroupTextBox.location = New-Object System.Drawing.Point(134,24)
64$ADGroupTextBox.Font = 'Microsoft Sans Serif,10'
65
66$MachineFilterTextBox = New-Object system.Windows.Forms.TextBox
67$MachineFilterTextBox.multiline = $false
68$MachineFilterTextBox.width = 215
69$MachineFilterTextBox.height = 18
70$MachineFilterTextBox.Anchor = $AnchorLeftRight
71$MachineFilterTextBox.location = New-Object System.Drawing.Point(134,61)
72$MachineFilterTextBox.Font = 'Microsoft Sans Serif,10'
73
74$SourceFolderTextBox1 = New-Object system.Windows.Forms.TextBox
75$SourceFolderTextBox1.multiline = $false
76$SourceFolderTextBox1.width = 215
77$SourceFolderTextBox1.Anchor = $AnchorLeftRight
78$SourceFolderTextBox1.height = 18
79$SourceFolderTextBox1.location = New-Object System.Drawing.Point(134,90)
80$SourceFolderTextBox1.Font = 'Microsoft Sans Serif,10'
81
82$SourceFolderTextBox2 = New-Object system.Windows.Forms.TextBox
83$SourceFolderTextBox2.multiline = $false
84$SourceFolderTextBox2.width = 215
85$SourceFolderTextBox2.height = 18
86$SourceFolderTextBox2.Anchor = $AnchorLeftRight
87$SourceFolderTextBox2.location = New-Object System.Drawing.Point(134,140)
88$SourceFolderTextBox2.Font = 'Microsoft Sans Serif,10'
89
90$DestinationFolderTextBox1 = New-Object system.Windows.Forms.TextBox
91$DestinationFolderTextBox1.multiline = $false
92$DestinationFolderTextBox1.width = 215
93$DestinationFolderTextBox1.height = 18
94$DestinationFolderTextBox1.Anchor = $AnchorLeftRight
95$DestinationFolderTextBox1.location = New-Object System.Drawing.Point(134,115)
96$DestinationFolderTextBox1.Font = 'Microsoft Sans Serif,10'
97
98$DestinationFolderTextBox2 = New-Object system.Windows.Forms.TextBox
99$DestinationFolderTextBox2.multiline = $false
100$DestinationFolderTextBox2.width = 215
101$DestinationFolderTextBox2.height = 18
102$DestinationFolderTextBox2.Anchor = $AnchorLeftRight
103$DestinationFolderTextBox2.location = New-Object System.Drawing.Point(134,165)
104$DestinationFolderTextBox2.Font = 'Microsoft Sans Serif,10'
105
106$ADGroupLabel = New-Object system.Windows.Forms.Label
107$ADGroupLabel.text = "AD Group"
108$ADGroupLabel.AutoSize = $true
109$ADGroupLabel.width = 25
110$ADGroupLabel.height = 10
111$ADGroupLabel.location = New-Object System.Drawing.Point(11,24)
112$ADGroupLabel.Font = 'Microsoft Sans Serif,10'
113
114$MachineFilterLabel = New-Object system.Windows.Forms.Label
115$MachineFilterLabel.text = "Machine Filter"
116$MachineFilterLabel.AutoSize = $true
117$MachineFilterLabel.width = 25
118$MachineFilterLabel.height = 10
119$MachineFilterLabel.location = New-Object System.Drawing.Point(11,61)
120$MachineFilterLabel.Font = 'Microsoft Sans Serif,10'
121
122$SourceFolderLabel1 = New-Object system.Windows.Forms.Label
123$SourceFolderLabel1.text = "Source Folder 1"
124$SourceFolderLabel1.AutoSize = $true
125$SourceFolderLabel1.width = 25
126$SourceFolderLabel1.height = 10
127$SourceFolderLabel1.location = New-Object System.Drawing.Point(11,90)
128$SourceFolderLabel1.Font = 'Microsoft Sans Serif,10'
129
130$SourceFolderLabel2 = New-Object system.Windows.Forms.Label
131$SourceFolderLabel2.text = "Source Folder 2"
132$SourceFolderLabel2.AutoSize = $true
133$SourceFolderLabel2.width = 25
134$SourceFolderLabel2.height = 10
135$SourceFolderLabel2.location = New-Object System.Drawing.Point(11,140)
136$SourceFolderLabel2.Font = 'Microsoft Sans Serif,10'
137
138$DestinationFolderLabel1 = New-Object system.Windows.Forms.Label
139$DestinationFolderLabel1.text = "Destination Folder 1"
140$DestinationFolderLabel1.AutoSize = $true
141$DestinationFolderLabel1.width = 25
142$DestinationFolderLabel1.height = 10
143$DestinationFolderLabel1.location = New-Object System.Drawing.Point(11,115)
144$DestinationFolderLabel1.Font = 'Microsoft Sans Serif,10'
145
146$DestinationFolderLabel2 = New-Object system.Windows.Forms.Label
147$DestinationFolderLabel2.text = "Destination Folder 2"
148$DestinationFolderLabel2.AutoSize = $true
149$DestinationFolderLabel2.width = 25
150$DestinationFolderLabel2.height = 10
151$DestinationFolderLabel2.location = New-Object System.Drawing.Point(11,165)
152$DestinationFolderLabel2.Font = 'Microsoft Sans Serif,10'
153
154$RunButton = New-Object system.Windows.Forms.Button
155$RunButton.text = "Run"
156$RunButton.width = 60
157$RunButton.height = 30
158$RunButton.Anchor = $AnchorRightBottom
159$RunButton.location = New-Object System.Drawing.Point(318,511)
160$RunButton.Font = 'Microsoft Sans Serif,10'
161
162$ProgressBar1 = New-Object system.Windows.Forms.ProgressBar
163$ProgressBar1.width = 279
164$ProgressBar1.height = 29
165$ProgressBar1.Anchor = $AnchorLeftRightBottom
166$ProgressBar1.location = New-Object System.Drawing.Point(19,512)
167
168$DataGridView1 = New-Object system.Windows.Forms.DataGridView
169$DataGridView1.width = 366
170$DataGridView1.height = 244
171$DataGridView1.Anchor = $AnchorAll
172$DataGridView1.location = New-Object System.Drawing.Point(16,242)
173
174
175$RefreshStatusButton = New-Object system.Windows.Forms.Button
176$RefreshStatusButton.text = "Refresh Status"
177$RefreshStatusButton.width = 130
178$RefreshStatusButton.height = 20
179$RefreshStatusButton.location = New-Object System.Drawing.Point(19,215)
180$RefreshStatusButton.Font = 'Microsoft Sans Serif,10'
181
182$RefreshListButton = New-Object system.Windows.Forms.Button
183$RefreshListButton.text = "Refresh List"
184$RefreshListButton.width = 130
185$RefreshListButton.height = 20
186$RefreshListButton.location = New-Object System.Drawing.Point(175,215)
187$RefreshListButton.Font = 'Microsoft Sans Serif,10'
188
189$FileDeployForm.controls.AddRange(@($SettingsGroupbox,$RunButton,$ProgressBar1,$DataGridView1,$RefreshStatusButton,$RefreshListButton))
190$SettingsGroupbox.controls.AddRange(@(
191 $ADGroupTextBox,
192 $MachineFilterTextBox,
193 $SourceFolderTextBox1,
194 $SourceFolderTextBox2,
195 $DestinationFolderTextBox1,
196 $DestinationFolderTextBox2,
197 $ADGroupLabel,
198 $MachineFilterLabel,
199 $SourceFolderLabel1,
200 $SourceFolderLabel2,
201 $DestinationFolderLabel1,
202 $DestinationFolderLabel2
203 ))
204
205#endregion GUI }
206
207#region gui events {
208$RefreshStatusButton.Add_Click({ RefreshStatus })
209$RefreshListButton.Add_Click({ RefreshList })
210$RunButton.Add_Click({ RunFileDeploy })
211$FileDeployForm.Add_Closing({ FormClosing })
212
213function RunFileDeploy{
214 $FileDeployForm.Hide()
215 $computers | Invoke-Parallel -ScriptBlock {
216 $computername = $_.Name
217 if(Test-Connection -Count 3 -ComputerName $computername -ErrorAction SilentlyContinue){
218 $mre = New-Object System.Threading.ManualResetEvent($false)
219 $status = "Online"
220 Invoke-SQLiteQuery -SQLiteConnection $connection -Query "UPDATE Computers SET status = '$status' WHERE computername = '$computername'"
221 if($SourceFolderTextBox1.Text -ne ""){
222 robocopy "$($SourceFolderTextBox1.Text)" "\\$(Join-Path -Path $computername -ChildPath $($DestinationFolderTextBox1.Text))" #> $copy1result
223 $copy1ExitCode = $LASTEXITCODE
224 $status += " | copy 1 exit code $copy1ExitCode"
225 }
226 if($SourceFolderTextBox2.Text -ne ""){
227 robocopy "$($SourceFolderTextBox2.Text)" "\\$(Join-Path -Path $computername -ChildPath $($DestinationFolderTextBox2.Text))" #> $copy1result
228 $copy2ExitCode = $LASTEXITCODE
229 $status += " | copy 2 exit code $copy2ExitCode"
230 }
231
232 #Disable "Welcome to Windows Media Player Page" to allow Window Media Player to start without prompting for settings
233 $registry = [wmiclass]"\\$computername\root\default:stdRegProv"
234 $registry.SetDWORDValue($hklm,$mediaPlayerKey,"FirstTime",1)
235 $registry.SetDWORDValue($hklm,$mediaPlayerKey,"AcceptedEULA",1)
236
237 $sidKeys = $registry.EnumKey($hklm, $profileListKey).sNames
238 foreach($sid in $sidKeys){
239 $imagePath = $registry.GetExpandedStringValue($hklm,(Join-Path -Path $profileListKey -ChildPath $sid),"ProfileImagePath").sValue
240 if($imagePath -eq "C:\Users\Hostlogin"){
241 $hostloginSid = $sid
242 }
243 }
244
245 $registry.SetDWORDValue($hku,(Join-Path -Path $hostloginSid -ChildPath $mediaPlayerKey),"AcceptedPrivacyStatement",1)
246 $registry.SetDWORDValue($hku,(Join-Path -Path $hostloginSid -ChildPath $mediaPlayerKey),"FirstRun",0)
247
248 $status += " | Complete"
249 Invoke-SQLiteQuery -SQLiteConnection $connection -Query "UPDATE Computers SET status = '$status' WHERE computername = '$computername'"
250 }
251 else{
252 Invoke-SQLiteQuery -SQLiteConnection $connection -Query "UPDATE Computers SET status = 'Offline' WHERE computername = '$computername'"
253 }
254 }
255 $FileDeployForm.Show()
256 RefreshStatus
257}
258
259function RefreshStatus{
260 $computerTable = Invoke-SqliteQuery -SQLiteConnection $connection -Query "SELECT * FROM Computers ORDER BY computername"
261 $DataGridView1.Columns.Clear()
262 $DataGridView1.Rows.Clear()
263 $DataGridView1.ColumnCount = ($computerTable | Get-Member | Where membertype -eq noteproperty).Count
264 for($i = 0; $i -lt $DataGridView1.ColumnCount; $i++){
265 $DataGridView1.Columns[$i].Name = ($computerTable | Get-Member | Where membertype -eq noteproperty)[$i].Name
266 }
267 $DataGridView1.AutoSizeColumnsMode = [System.Windows.Forms.DataGridViewAutoSizeColumnsMode]::AllCells
268 foreach($computer in $computerTable){
269 $rowIndex = $DataGridView1.Rows.Add(($computer.computername,$computer.status))
270 }
271}
272
273function RefreshList{
274 $computers = Get-ADComputer -Filter $MachineFilterTextBox.Text -SearchBase $ADGroupTextBox.Text -Properties Name
275 Set-Variable -Name computers -Value $computers -Scope Global
276 #Set up datatable to store results
277 $datatable = $computers | %{
278 [pscustomobject]@{
279 computername = $($_.Name).ToUpper()
280 status = ""
281 }
282 }| Out-DataTable
283
284 #Set up SQLite in-memory database
285 $connection = New-SQLiteConnection -DataSource (Join-Path -Path $scriptPath -ChildPath Computers.sqlite) -ErrorAction SilentlyContinue
286 Set-Variable -Name connection -Value $connection -Scope Global
287 #Create basic table for storing results
288 Invoke-SqliteQuery -SQLiteConnection $connection -Query "CREATE TABLE IF NOT EXISTS Computers (computername TEXT PRIMARY KEY, status TEXT); DELETE FROM Computers"
289
290 #Copy datatable to database
291 Invoke-SQLiteBulkCopy -DataTable $datatable -SQLiteConnection $connection -Table Computers -Force
292 RefreshStatus
293}
294
295function FormClosing{
296 $settings.AdGroup =$ADGroupTextBox.Text
297 $settings.MachineFilter = $MachineFilterTextBox.Text
298 $settings.Destination1 = $DestinationFolderTextBox1.Text
299 $settings.Destination2 = $DestinationFolderTextBox2.Text
300 $settings.Source1 = $SourceFolderTextBox1.Text
301 $settings.Source2 = $SourceFolderTextBox2.Text
302 $settings | Export-Clixml -Path $scriptPath\settings.xml
303}
304
305
306$ADGroupTextBox.Text = $settings.AdGroup
307$MachineFilterTextBox.Text = $settings.MachineFilter
308$DestinationFolderTextBox1.Text = $settings.Destination1
309$DestinationFolderTextBox2.Text = $settings.Destination2
310$SourceFolderTextBox1.Text = $settings.Source1
311$SourceFolderTextBox2.Text = $settings.Source2
312RefreshList
313RefreshStatus
314[void]$FileDeployForm.ShowDialog()