最終更新 1 year ago

migrate-shares.ps1 Raw
1 # File Share and Permissions Migration Script
2
3# Parameters
4param (
5 [string]$SourceServer,
6 [string]$DestinationServer,
7 [switch]$DryRun,
8 [switch]$Help,
9 [ValidateSet('Skip', 'Replace', 'Prompt')]
10 [string]$ExistingShareAction = 'Prompt'
11)
12
13# Function to display usage information
14function Show-UsageInfo {
15 @"
16File Share Migration Script
17
18Usage:
19 .\MigrateFileShares.ps1 -SourceServer <SourceServerName> -DestinationServer <DestinationServerName> [-DryRun] [-ExistingShareAction <Skip|Replace|Prompt>]
20
21Parameters:
22 -SourceServer (Required) Name of the source file server
23 -DestinationServer (Required) Name of the destination file server
24 -DryRun (Optional) Preview migration actions without making changes
25 -Help (Optional) Show this usage information
26 -ExistingShareAction (Optional) How to handle existing shares
27 Skip - Skip shares that already exist
28 Replace - Remove and recreate existing shares
29 Prompt - Ask for each existing share (default)
30
31Examples:
32 # Preview migration actions
33 .\MigrateFileShares.ps1 -SourceServer SOURCESVR -DestinationServer DESTSVR -DryRun
34
35 # Perform actual migration, skipping existing shares
36 .\MigrateFileShares.ps1 -SourceServer SOURCESVR -DestinationServer DESTSVR -ExistingShareAction Skip
37
38 # Perform actual migration, replacing existing shares
39 .\MigrateFileShares.ps1 -SourceServer SOURCESVR -DestinationServer DESTSVR -ExistingShareAction Replace
40
41Notes:
42 - Requires administrative privileges
43 - Ensure PowerShell remoting is enabled between servers
44 - Test in a staged environment before production use
45"@
46}
47
48# Check if help is requested or required parameters are missing
49if ($Help -or [string]::IsNullOrWhiteSpace($SourceServer) -or [string]::IsNullOrWhiteSpace($DestinationServer)) {
50 Show-UsageInfo
51 exit
52}
53
54# Logging function
55function Write-MigrationLog {
56 param (
57 [string]$Message,
58 [switch]$DryRun
59 )
60
61 $logPrefix = if ($DryRun) { "[DRY RUN] " } else { "[ACTUAL] " }
62 Write-Host "$logPrefix$Message"
63}
64
65# Function to get detailed share information
66function Get-ShareDetails {
67 param (
68 [string]$ServerName
69 )
70
71 # Get all file shares
72 $shares = Get-SmbShare -CimSession $ServerName | Where-Object {
73 $_.Special -eq $false -and
74 $_.Name -notlike "IPC$" -and
75 $_.Name -notlike "ADMIN$"
76 }
77
78 $shareDetails = @()
79
80 foreach ($share in $shares) {
81 # Get share path
82 $sharePath = $share.Path
83
84 # Safely get NTFS permissions
85 $ntfsPermissions = $null
86 try {
87 $ntfsPermissions = Get-Acl $sharePath -ErrorAction Stop
88 }
89 catch {
90 Write-Warning "Could not retrieve NTFS permissions for $sharePath. Using minimal default permissions."
91 $ntfsPermissions = New-Object System.Security.AccessControl.DirectorySecurity
92 }
93
94 # Safely get SMB share permissions
95 $smbPermissions = $null
96 try {
97 $smbPermissions = Get-SmbShareAccess -Name $share.Name -CimSession $ServerName -ErrorAction Stop
98 }
99 catch {
100 Write-Warning "Could not retrieve SMB permissions for share $($share.Name). Using minimal default permissions."
101 $smbPermissions = @()
102 }
103
104 $shareDetails += [PSCustomObject]@{
105 Name = $share.Name
106 Path = $sharePath
107 Description = $share.Description
108 NTFSPermissions = $ntfsPermissions
109 SMBPermissions = $smbPermissions
110 }
111 }
112
113 return $shareDetails
114}
115
116# Function to check if share exists on destination
117function Test-ShareExists {
118 param (
119 [string]$ShareName,
120 [string]$DestServer
121 )
122
123 $existingShare = Get-SmbShare -Name $ShareName -CimSession $DestServer -ErrorAction SilentlyContinue
124 return ($existingShare -ne $null)
125}
126
127# Function to create shares and set permissions
128function Create-ShareAndPermissions {
129 param (
130 [PSCustomObject]$ShareDetail,
131 [bool]$IsDryRun,
132 [string]$ExistingAction
133 )
134
135 # Check if share already exists
136 $shareExists = Test-ShareExists -ShareName $ShareDetail.Name -DestServer $DestinationServer
137
138 # Determine action for existing share
139 $processShare = $true
140 if ($shareExists) {
141 switch ($ExistingAction) {
142 'Skip' {
143 Write-MigrationLog -Message "Skipping existing share: $($ShareDetail.Name)" -DryRun:$IsDryRun
144 $processShare = $false
145 }
146 'Replace' {
147 Write-MigrationLog -Message "Will replace existing share: $($ShareDetail.Name)" -DryRun:$IsDryRun
148 if (-not $IsDryRun) {
149 Remove-SmbShare -Name $ShareDetail.Name -Force -CimSession $DestinationServer
150 }
151 }
152 'Prompt' {
153 $userChoice = Read-Host "Share '$($ShareDetail.Name)' already exists. Replace? (Y/N)"
154 if ($userChoice -ne 'Y') {
155 Write-MigrationLog -Message "Skipping existing share: $($ShareDetail.Name)" -DryRun:$IsDryRun
156 $processShare = $false
157 }
158 else {
159 if (-not $IsDryRun) {
160 Remove-SmbShare -Name $ShareDetail.Name -Force -CimSession $DestinationServer
161 }
162 }
163 }
164 }
165 }
166
167 # Proceed with share creation if required
168 if ($processShare) {
169 # Log directory creation
170 if (-not (Test-Path $ShareDetail.Path)) {
171 Write-MigrationLog -Message "Would create directory: $($ShareDetail.Path)" -DryRun:$IsDryRun
172
173 if (-not $IsDryRun) {
174 New-Item -ItemType Directory -Path $ShareDetail.Path -Force | Out-Null
175 }
176 }
177
178 # Log share creation
179 Write-MigrationLog -Message "Would create SMB Share: $($ShareDetail.Name)" -DryRun:$IsDryRun
180 if (-not $IsDryRun) {
181 New-SmbShare -Name $ShareDetail.Name -Path $ShareDetail.Path -Description $ShareDetail.Description -CimSession $DestinationServer | Out-Null
182 }
183
184 # Log and set NTFS Permissions
185 Write-MigrationLog -Message "Would set NTFS Permissions for: $($ShareDetail.Path)" -DryRun:$IsDryRun
186 if (-not $IsDryRun) {
187 if ($ShareDetail.NTFSPermissions) {
188 $ShareDetail.NTFSPermissions | Set-Acl $ShareDetail.Path
189 }
190 }
191
192 # Log and set SMB Share Permissions
193 if ($ShareDetail.SMBPermissions) {
194 foreach ($permission in $ShareDetail.SMBPermissions) {
195 Write-MigrationLog -Message "Would grant SMB Access: $($permission.AccountName) on $($ShareDetail.Name)" -DryRun:$IsDryRun
196
197 if (-not $IsDryRun) {
198 Grant-SmbShareAccess -Name $ShareDetail.Name -AccountName $permission.AccountName -AccessRight $permission.AccessRight -Force -CimSession $DestinationServer | Out-Null
199 }
200 }
201 }
202 }
203}
204
205# Main Migration Process
206function Migrate-FileShares {
207 param (
208 [bool]$IsDryRun,
209 [string]$ExistingAction
210 )
211
212 # Get share details from source server
213 $sourceShares = Get-ShareDetails -ServerName $SourceServer
214
215 Write-Host "=== Share Migration Summary ===="
216 Write-Host "Source Server: $SourceServer"
217 Write-Host "Destination Server: $DestinationServer"
218 Write-Host "Dry Run Mode: $IsDryRun"
219 Write-Host "Existing Share Action: $ExistingAction"
220 Write-Host "Total Shares Found: $($sourceShares.Count)"
221 Write-Host "==============================="
222
223 # Create shares and set permissions on destination server
224 foreach ($share in $sourceShares) {
225 Create-ShareAndPermissions -ShareDetail $share -IsDryRun $IsDryRun -ExistingAction $ExistingAction
226 }
227}
228
229# Execute Migration
230Migrate-FileShares -IsDryRun:$DryRun -ExistingAction $ExistingShareAction
231
232# Optional: Completion message
233if (-not $DryRun) {
234 Write-Host "File share migration completed."
235}