/
ASRRestoreOneDrive.ps1
176 lines (162 loc) · 7.42 KB
/
ASRRestoreOneDrive.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<#
MIT License
Copyright (c) Thextrabit.com.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
#>
function audit($message)
{
write-host $message
add-content $auditFile "$(get-date -f "dd-MM-yyyy HH:mm:ss") - $message"
}
function scriptResult($siteURL,$status,$reason)
{
return New-Object PSObject -Property @{
'siteURL' = $siteURL
'Status' = $status
'Reason' = $reason
}
}
# Must have PNP.PowerShell and Microsoft.Online.SharePoint.PowerShell
# No checks for the modules in this script but uncomment once to install (requires elevated PowerShell window)
#Install-Module -Name PNP.PowerShell
#Install-Module -Name Microsoft.Online.SharePoint.PowerShell
# FLAG FOR AUDIT ONLY - setting this to true will only audit and not restore any files. Note: logging remains the same so it will
$auditOnly = $false
# Set up working directory for output Files, change to desired location
$workingDir = "C:\Users\Public\Documents\"
$auditFile = $workingDir + (get-date -f "yyyyMMdd_HHmm") + "_ASRlinkRestore.txt"
# This is the date we want to check from (13/01 = start of ASR rule problems)
$startDate = get-date -Year 2023 -Month 1 -Day 13 -Hour 0 -Minute 0 -Second 0
# Specify your tenant name here
$tenant = "yourTenantName"
# Specify UPN of the account being used to run this
$secondaryAdmin = "username@domain.com"
# Once credentials entered to connect to SPO and PNP should be cached for the session
# Needs to be SharePoint admin or Global Admin
Connect-SPOService -Url "https://$tenant-admin.sharepoint.com"
Connect-PnPOnline -Url "https://$tenant.sharepoint.com/" -Interactive
$allOneDriveSites = Get-SPOSite -IncludePersonalSite $true -Limit all -Filter "Url -like '-my.sharepoint.com/personal/'" `
| Where-Object {$_.Status -eq "Active"}
# Arrays for results
$fileResults = @()
$scriptResults = @()
$counter = 1
foreach ($site in $allOneDriveSites)
{
write-host "Processing site $counter out of $($allOneDriveSites.count)" -ForegroundColor Magenta
try
{
# try to add secondary site collection admin required to read content
try
{
audit("Adding user $SecondaryAdmin as site collection admin to $($site.URL)")
Set-SPOUser -Site $site.URL -LoginName $SecondaryAdmin -IsSiteCollectionAdmin $True -ErrorAction Stop | Out-Null
#Start-Sleep -Seconds 1
}
catch
{
#write error, if this has failed we skip this OneDrive
audit("Failed to add user $SecondaryAdmin as site collection admin to $($site.URL)")
$scriptResults += scriptResult -siteURL $site.URL -status "Failed" -reason "Failed to add site collection admin"
continue
}
try
{
audit("Connecting via PNP to $($site.URL)")
Connect-PnPOnline -Url $site.URL -Interactive -ErrorAction Stop # -Credentials $creds
}
catch
{
audit("Failed PNP connection to site $($site.URL)")
$scriptResults += scriptResults -siteURL $site.URL -status "Failed" -reason "Failed PNP connection to site"
continue
}
# Double check that we are connected to the right site, if not do nothing
$pnpSite = Get-PnPSite
If ($pnpSite.URL -eq $site.Url)
{
audit("Searching for deleted .lnk files")
$deletedLinks = Get-PnPRecycleBinItem -FirstStage | where-object {$_.DeletedDate -gt $startDate -and $_.Title -like "*.lnk"}
# Loop through all the links found, log and restore them
foreach ($link in $deletedLinks)
{
try
{
audit("Attempting to restore file $($link.Title)")
If ($auditOnly -eq $false)
{
Restore-PnPRecycleBinItem -Identity $link -Force -ErrorAction Stop
}
audit("Successfully restored file $($link.Title)")
$fileResults += New-Object PSObject -Property @{
'SiteURL' = $site.URL
'FileName' = $link.Title
'DeletedDate' = $link.DeletedDate
'DirName' = $link.DirName
'Restored' = "Y"
}
}
catch
{
audit("Failed to restore file $($link.Title)")
$fileResults += New-Object PSObject -Property @{
'SiteURL' = $site.URL
'FileName' = $link.Title
'DeletedDate' = $link.DeletedDate
'DirName' = $link.DirName
'Restored' = "N"
}
}
}
}
else
{
audit("Connected site $($pnpSite.URL) is not $($site.URL), skipping")
continue
}
}
catch
{
# Nothing to do
}
# Remove secondary site collection admin
Finally
{
$counter++
try
{
# Code to not remove myself from my own OneDrive(s), not required if run under service account
if ($site.owner -ne $secondaryAdmin)
{
audit("Removing user $SecondaryAdmin from $($site.URL)")
Set-SPOUser -Site $site.URL -LoginName $SecondaryAdmin -IsSiteCollectionAdmin $false -ErrorAction Stop | Out-Null
audit("Successfully removed user $SecondaryAdmin from $($site.URL)")
}
$scriptResults += scriptResult -siteURL $site.URL -status "Success" -reason ""
}
catch
{
# write error
audit("Failed to remove user $SecondaryAdmin from $($site.URL)")
$scriptResults += scriptResult -siteURL $site.URL -status "Failed" -reason "Failed to remove site collection admin"
}
}
}
$scriptResults | select siteURL, Status, Reason | export-csv ($workingDir + (get-date -f "yyyyMMdd_HHmm") + "_ODLinkRestoreSiteReport.csv") -NoTypeInformation
$fileResults | select siteURL, FileName, DirName, DeletedDate, Restored | export-csv ($workingDir + (get-date -f "yyyyMMdd_HHmm") + "_ODLinkRestoreResults.csv") -NoTypeInformation
Disconnect-PnPOnline
Disconnect-SPOService