├── BoxAuth
└── BoxAuth.psm1
├── BoxContent
└── BoxContent.psm1
├── BoxGroup
└── BoxGroup.psm1
├── BoxUser
└── BoxUser.psm1
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── box
└── Box.psm1
├── images
└── box-dev-logo-clip.png
└── samples
├── GenerateAccessTokens.ps1
├── GetUsersFromBox.ps1
├── SetQuota.ps1
├── SetQuota2.ps1
└── syncADgroups.ps1
/BoxAuth/BoxAuth.psm1:
--------------------------------------------------------------------------------
1 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
2 |
3 | # Function to get initial OAuth token
4 | function New-BoxoAUTHCode($clientID)
5 | {
6 | $sec_token_sent = "security_token%3DKnhMJatFipTAnM0nHlZA"
7 | $uri = "https://www.box.com/api/oauth2/authorize?response_type=code&client_id=$clientID&state=$sec_token_sent"
8 |
9 | Write-Host "Please visit the URL, authorize the app and note the code value returned."
10 | Write-Host "You have 30 seconds to paste the resulting URL." -ForegroundColor Yellow
11 | Write-Host "The URL is $uri"
12 |
13 | $val = Read-Host "Ready? [Y - launch a browser to URL, N - Do it manually]"
14 | if($val.ToUpper() -eq "Y")
15 | {
16 | Start-Process $uri
17 | }
18 |
19 | $response = Read-Host "Paste return URL."
20 |
21 | $sec_token = $response.Split('=')[1].Substring(0,$response.Split('=')[1].Length - 5)
22 | if($sec_token_sent -ne $sec_token)
23 | {
24 | Write-Host "Warning: Security tokens do not match!" -ForegroundColor Red
25 | }
26 |
27 | return $response.Split('=')[2]
28 | }
29 | # Function to get new OAuth tokens saved to registry
30 | function New-BoxAccessTokens($clientID, $client_secret,$code)
31 | {
32 | $data = "grant_type=authorization_code&code=" + $code + "&client_id=" + $clientID + "&client_secret=" + $client_secret
33 | $uri = "https://www.box.com/api/oauth2/token"
34 |
35 | $json = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/x-www-form-urlencoded" -Body $data
36 |
37 |
38 | $reg_key = "HKLM:\SOFTWARE\BoxAPI"
39 |
40 | if(-not (Test-Path $reg_key))
41 | {
42 | $response = Read-Host "Registry key $reg_key does not exist. Create (requires Administrative rights)? [Y/N]"
43 | if($response.ToUpper() -eq "Y")
44 | {
45 | try{
46 | $reg = New-Item $reg_key -ItemType Registry -Force
47 | }
48 | catch
49 | {
50 | Write-Host "Unable to write to registry."
51 | return $false
52 | }
53 | }
54 | else {return $false}
55 | }
56 |
57 | #write registry entries
58 | $reg = New-ItemProperty -Path $reg_key -Name "access_token" -Value $json.access_token -Force
59 | $reg = New-ItemProperty -Path $reg_key -Name "refresh_token" -Value $json.refresh_token -Force
60 | $reg = New-ItemProperty -Path $reg_key -Name "token_time" -Value (Get-date -Format "yyyy-MM-dd HH:mm:ss") -Force
61 |
62 | return $true
63 | }
64 | # Function to get new OAuth tokens, but save tokens to a secure directory
65 | function New-BoxAccessTokens($clientID,$client_secret,$code,$secure_dir)
66 | {
67 | $data = "grant_type=authorization_code&code=" + $code + "&client_id=" + $clientID + "&client_secret=" + $client_secret
68 | Write-Host $data
69 | $uri = "https://www.box.com/api/oauth2/token"
70 |
71 | $json = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/x-www-form-urlencoded" -Body $data
72 | Write-Host $json
73 |
74 | if(-not (Test-Path $secure_dir))
75 | {
76 | $response = Read-Host "Secured directory $secure_dir does not exist. Create (requires Administrative rights)? [Y/N]"
77 | if($response.ToUpper() -eq "Y")
78 | {
79 | try{
80 | $dir = New-Item -path $secure_dir -ItemType "directory"
81 | }
82 | catch
83 | {
84 | Write-Host "Unable to create directory."
85 | return $false
86 | }
87 | }
88 | else {return $false}
89 | }
90 |
91 | $second = ConvertTo-SecureString -AsPlainText (Get-date -Format "yyyy-MM-dd HH:mm:ss") -Force
92 | $unsecure_date = (Get-date -Format "yyyy-MM-dd HH:mm:ss")
93 | $secure_date = ConvertTo-SecureString -AsPlainText $unsecure_date -Force
94 |
95 | $secure_access_token = ConvertFrom-SecureString $json.access_token
96 | $secure_refresh_token = ConvertFrom-SecureString $json.refresh_token
97 | $secure_token_time = ConvertFrom-SecureString -SecureString $secure_date
98 |
99 | #write secure files out
100 | $dir = New-ItemProperty -Path $secure_dir -Name "access_token" -Value $json.access_token -Force
101 | $dir = New-ItemProperty -Path $secure_dir -Name "refresh_token" -Value $json.refresh_token -Force
102 | $dir = New-ItemProperty -Path $secure_dir -Name "token_time" -Value (Get-date -Format "yyyy-MM-dd HH:mm:ss") -Force
103 |
104 | return $true
105 | }
106 | # Function to check existing access token and decide if a new one is needed, if so get it using refresh token and update them in registry
107 | function Get-BoxToken($clientID, $client_secret)
108 | {
109 | ## $debug_log can be used to dump verbose information regarding token issues. By default it does not write the debug to the log.
110 |
111 | $debug_log = ""
112 | $reg_key = "HKLM:\SOFTWARE\BoxAPI"
113 |
114 | $last_refresh = Get-ItemProperty -Path $reg_key -Name "token_time"
115 |
116 | $debug_log += "Last refresh time was $($last_refresh.token_time)`r`n"
117 | $debug_log += "Current token is $($(Get-ItemProperty -Path $reg_key -Name "access_token").access_token) `r`n"
118 | $debug_log += "Current refresh token is $($(Get-ItemProperty -Path $reg_key -Name "refresh_token").refresh_token)`r`n"
119 |
120 | #check the last refresh
121 | if(((Get-Date $last_refresh.token_time).AddHours(1)) -le (Get-Date))
122 | {
123 | $debug_log += "Current token is expired - current time is $(Get-Date)`r`n"
124 |
125 | #if the token age is over a hour, we need to refresh
126 | $refresh_token = (Get-ItemProperty -Path $reg_key -Name "refresh_token").refresh_token
127 | $uri = "https://www.box.com/api/oauth2/token"
128 | $data = "grant_type=refresh_token&refresh_token=" + $refresh_token + "&client_id=" + $clientID + "&client_secret=" + $client_secret
129 |
130 | try{
131 | $json = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/x-www-form-urlencoded" -Body $data
132 | }
133 | catch{
134 |
135 | $debug_log += "Error on API call:`r`n$_`r`n"
136 | #$debug_log | Out-File c:\scripts\box\debug.txt -Append
137 |
138 |
139 | return $null
140 | }
141 |
142 | $debug_log += "Query sent. Result:`r`n $json"
143 |
144 | #update registry values
145 | $reg = Set-ItemProperty -Path $reg_key -Name "refresh_token" -Value $json.refresh_token -Force
146 | $reg = Set-ItemProperty -Path $reg_key -Name "token_time" -Value (Get-date -Format "yyyy-MM-dd HH:mm:ss") -Force
147 | $reg = Set-ItemProperty -Path $reg_key -Name "access_token" -Value $json.access_token -Force
148 |
149 | $debug_log += "New refresh time is $($(Get-ItemProperty -Path $reg_key -Name "token_time").token_time)`r`n"
150 | $debug_log += "New token is $($(Get-ItemProperty -Path $reg_key -Name "access_token").access_token)`r`n"
151 | $debug_log += "New refresh token is $($(Get-ItemProperty -Path $reg_key -Name "refresh_token").refresh_token)`r`n"
152 |
153 | #$debug_log | Out-File c:\scripts\box\debug.txt -Append
154 |
155 | return $json.access_token
156 | }
157 | else
158 | {
159 | $debug_log += "Current time is $(Get-Date)`r`n"
160 | $debug_log += "Current token is still valid`r`n"
161 |
162 | #$debug_log | Out-File c:\scripts\box\debug.txt -Append
163 |
164 | #the token is still valid
165 | return (Get-ItemProperty -Path $reg_key -Name "access_token").access_token
166 | }
167 | }
168 | # Function to check existing access token and decide if a new one is needed, if so get it using refresh token and update in secure_dir files
169 | function Get-BoxTokenFromFile($cid, $cs, $secure_dir)
170 | {
171 |
172 | $debug_log = ""
173 | $token_time_file = "$secure_dir\token-time"
174 | $refresh_token_file = "$secure_dir\refresh-token"
175 | $access_token_file = "$secure_dir\access-token"
176 | $last_refresh = Get-Content -Path $token_time_file
177 | $refresh_token = Get-Content -Path $refresh_token_file
178 | $access_token = Get-Content -Path $access_token_file
179 | $debug_file = "e:\scripts\box\debug.txt"
180 |
181 | #$last_refresh
182 |
183 | $debug_log += "Last refresh time was $last_refresh`r`n"
184 | #$debug_log += "Current token is $access_token`r`n"
185 | #$debug_log += "Current refresh token is $refresh_token`r`n"
186 |
187 | #check the last refresh
188 | if(((Get-Date $last_refresh).AddMinutes(58)) -le (Get-Date))
189 | {
190 | $debug_log += "Current token is expired - current time is $(Get-Date)`r`n"
191 |
192 | #if the token age is over a hour, we need to refresh
193 | $uri = "https://app.box.com/api/oauth2/token”
194 | $data = "grant_type=refresh_token&refresh_token=$refresh_token&client_id=$cid&client_secret=$cs"
195 |
196 | try{
197 | $json = Invoke-RestMethod -Uri $uri -Method Post -Body $data
198 | }
199 | catch{
200 |
201 | $debug_log += "Error on API call:`r`n$_`r`n"
202 | $debug_log | Out-File $debug_file -Append
203 |
204 |
205 | return $null
206 | }
207 |
208 | $debug_log += "Query sent. Result:`r`n $json"
209 |
210 | #update files with new oauth data
211 | $json.refresh_token > $refresh_token_file
212 | $new_token_time = (Get-date -Format "yyyy-MM-dd HH:mm:ss")
213 | $new_token_time > $token_time_file
214 | $json.access_token > $access_token_file
215 |
216 | $debug_log += "New refresh time is $new_token_time`r`n"
217 | #$debug_log += "New token is $json.access_token`r`n"
218 | #$debug_log += "New refresh token is $json.refresh_token`r`n"
219 |
220 | $debug_log | Out-File $debug_file -Append
221 |
222 | return $json.access_token
223 | }
224 | else
225 | {
226 | $debug_log += "Current time is $(Get-Date)`r`n"
227 | $debug_log += "Current token is still valid`r`n"
228 |
229 | $debug_log | Out-File $debug_file -Append
230 |
231 | #the token is still valid
232 | return $access_token
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/BoxContent/BoxContent.psm1:
--------------------------------------------------------------------------------
1 | #retuns the specified folder
2 | function Get-BoxFolder($token, $id)
3 | {
4 | $uri = "https://api.box.com/2.0/folders/$id"
5 | $headers = @{"Authorization"="Bearer $token"}
6 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
7 |
8 | return $return
9 | }
10 |
11 | #returns the items contained in a specified folder
12 | function Get-BoxFolderItems($token, $id)
13 | {
14 | $uri = "https://api.box.com/2.0/folders/$id/items"
15 | $headers = @{"Authorization"="Bearer $token"}
16 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
17 |
18 | return $return.entries
19 | }
20 |
21 | #returns the folder collaborators
22 | function Get-BoxFolderCollabs($token, $id)
23 | {
24 | $uri = "https://api.box.com/2.0/folders/$id/collaborations"
25 | $headers = @{"Authorization"="Bearer $token"}
26 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
27 |
28 | return $return.entries
29 | }
30 |
31 | #creates a new folder under the provided parent
32 | function New-BoxFolder($token, $parent, $name)
33 | {
34 | $uri = "https://api.box.com/2.0/folders"
35 | $headers = @{"Authorization"="Bearer $token"}
36 |
37 | $json = '{'
38 | $json += '"name": "' + $name + '",'
39 | $json += '"parent": {"id":"' + $parent + '"}'
40 | $json += '}'
41 |
42 | $result = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/json"
43 |
44 | return $result.id
45 | }
46 |
47 | #copy all of a users content
48 |
--------------------------------------------------------------------------------
/BoxGroup/BoxGroup.psm1:
--------------------------------------------------------------------------------
1 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
2 |
3 | # Group Functions
4 | function New-BoxGroup()
5 | {
6 | param(
7 | [Parameter(Mandatory=$true)] [string] $token,
8 | [Parameter(Mandatory=$true)] [string] $name,
9 | [string] $description,
10 | $external_id,
11 | $provenance,
12 | $invitability,
13 | $viewability
14 | )
15 |
16 | #invitability_level and member_viewability_level support the following options:
17 | #admins_only
18 | #admins_and_members
19 | #all_managed_users
20 |
21 | #create a new Box group with the name given in $name
22 | #returns the groupid
23 |
24 | $uri = "https://api.box.com/2.0/groups"
25 | $headers = @{"Authorization"="Bearer $token"}
26 |
27 | #build JSON - name is the only mandatory field
28 | $json = '{'
29 | $json += '"name": "' + $name
30 |
31 | if($provenance){ $json += '", "provenance": "' + $provenance}
32 | if($description){ $json += '", "description": "' + $description}
33 | if($external_id){ $json += '", "external_sync_identifier": "' + $external_id}
34 | if($invitability){ $json += '", "invitability_level": "' + $invitability}
35 | if($viewability){ $json += '", "member_viewability_level": "' + $viewability}
36 |
37 | $json += '"}'
38 |
39 | $return = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/json"
40 |
41 | return $return.id
42 | }
43 |
44 | function Set-BoxGroup()
45 | {
46 | param(
47 | [Parameter(Mandatory=$true)] [string] $token,
48 | [Parameter(Mandatory=$true)] [string] $groupID,
49 | $name,
50 | [string] $description,
51 | $external_id,
52 | $provenance,
53 | $invitability,
54 | $viewability
55 | )
56 |
57 | #invitability_level and member_viewability_level support the following options:
58 | #admins_only
59 | #admins_and_members
60 | #all_managed_users
61 |
62 | #create a new Box group with the name given in $name
63 | #returns the groupid
64 |
65 | $uri = "https://api.box.com/2.0/groups/" + $groupID
66 | $headers = @{"Authorization"="Bearer $token"}
67 |
68 | #build JSON - no mandatory fields
69 |
70 | $json = '{'
71 |
72 | if($name){$json += '"name": "' + $name + '", '}
73 | if($provenance){ $json += '"provenance": "' + $provenance + '", '}
74 | if($description){ $json += '"description": "' + $description + '", '}
75 | if($external_id){ $json += '"external_sync_identifier": "' + $external_id + '", '}
76 | if($invitability){ $json += '"invitability_level": "' + $invitability + '", '}
77 | if($viewability){ $json += '"member_viewability_level": "' + $viewability + '", '}
78 |
79 | $json = $json.Substring(0,$json.Length - 3)
80 |
81 | $json += '"}'
82 |
83 | $return = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -Body $json -ContentType "application/json"
84 |
85 | return $return.id
86 | }
87 |
88 | function Remove-BoxGroup($token, $groupID)
89 | {
90 | #deletes the given group based on group ID
91 |
92 | $uri = "https://api.box.com/2.0/groups/$groupID"
93 | $headers = @{"Authorization"="Bearer $token"}
94 |
95 | $return = Invoke-RestMethod -Uri $uri -Method Delete -Headers $headers -ContentType "application/x-www-form-urlencoded"
96 | }
97 |
98 | function Add-BoxGroupMember($token, $userID, $groupID)
99 | {
100 | #adds selected member to given group
101 | #return group member detail
102 |
103 | $uri = "https://api.box.com/2.0/group_memberships"
104 | $headers = @{"Authorization"="Bearer $token"}
105 | $json = '{ "user": { "id": "' + $userID + '"}, "group": { "id": "' + $groupID + '" } }'
106 |
107 | $return = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/json"
108 |
109 | }
110 |
111 | function Remove-BoxGroupMember($token, $userID, $groupID)
112 | {
113 | $members = Get-BoxGroupDetails -token $token -groupID $groupID
114 |
115 | for($i = 0; $i -lt $members.Count; $i++)
116 | {
117 | if($members[$i].user.id -eq $userID)
118 | {
119 | $membershipID = $members[$i].id
120 | $i = $members.Count + 1
121 | }
122 | }
123 |
124 | $result = Remove-BoxGroupMembership -token $token -membershipID $membershipID
125 | }
126 |
127 | function Remove-BoxGroupMembership($token, $membershipID)
128 | {
129 | #deletes the given membership based on membership ID
130 |
131 | $uri = "https://api.box.com/2.0/group_memberships/$membershipID"
132 | $headers = @{"Authorization"="Bearer $token"}
133 |
134 | $return = Invoke-RestMethod -Uri $uri -Method Delete -Headers $headers -ContentType "application/x-www-form-urlencoded"
135 | }
136 |
137 | function Get-BoxGroupMembers($groupID, $token)
138 | {
139 | #input: group id, token
140 | #output: group membership in hash table of name, ID
141 |
142 | $uri = "https://api.box.com/2.0/groups/$groupID/memberships"
143 | $headers = @{"Authorization"="Bearer $token"}
144 |
145 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
146 |
147 | $var = @{} #variable to hold the member hash table
148 |
149 | #this is the base case of the first 100 members
150 |
151 | $members = $return.entries
152 |
153 | foreach($member in $members.user)
154 | {
155 | $var.Add($member.login,$member.id)
156 | }
157 |
158 | if($return.total_count -le $return.limit)
159 | {
160 | #there are no more than 100 members, no need to make additional API calls
161 | return $var
162 | }
163 | else
164 | {
165 | #more than 100 members exist so additional API calls are needed until total_count is reached
166 |
167 | $returned = $return.limit #update the number returned so far
168 |
169 | #iterate through the remaining entries in 100 member pages
170 | while($returned -le $return.total_count)
171 | {
172 | $uri = "https://api.box.com/2.0/groups/$groupID/memberships?offset=$returned"
173 | $more_return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
174 | $members = $more_return.entries
175 | $returned += $more_return.limit
176 |
177 | foreach($member in $members.user)
178 | {
179 | $var.Add($member.login,$member.id)
180 | }
181 | }
182 |
183 | return $var
184 | }
185 | }
186 |
187 | function Get-BoxAllGroups($token)
188 | {
189 | $uri = "https://api.box.com/2.0/groups?fields=name,description,provenance,external_sync_identifier,invitability_level,member_viewability_level"
190 | $headers = @{"Authorization"="Bearer $token"}
191 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
192 |
193 | #by default, only 100 groups are returned. If more groups exist, they must be iterated through in sets of 1000
194 | if($return.total_count -le $return.limit)
195 | {
196 | return $return.entries
197 | }
198 | else
199 | {
200 | $returned = $return.limit
201 |
202 | $groups = $return.entries
203 |
204 | while($returned -le $return.total_count)
205 | {
206 | #get the next batch of groups
207 | $uri = "https://api.box.com/2.0/groups?fields=name,description,provenance,external_sync_identifier,invitability_level,member_viewability_level,limit=1000&offset=$returned"
208 | $more_return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
209 | $groups += $more_return.entries
210 | $returned += $more_return.limit
211 | }
212 | return $groups
213 | }
214 | }
215 |
216 | function Get-BoxGroupDetails($token, $groupID)
217 | {
218 | #input: group id
219 | #output: group details including partial member list
220 | $uri = "https://api.box.com/2.0/groups/$groupID/memberships"
221 | $headers = @{"Authorization"="Bearer $token"}
222 |
223 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
224 |
225 | return $return.entries
226 | }
227 |
228 | function Get-BoxGroup($token, $groupID)
229 | {
230 | #input: group id
231 | #output: group fields
232 | $uri = "https://api.box.com/2.0/groups/$groupID" + "?fields=name,description,provenance,external_sync_identifier,invitability_level,member_viewability_level"
233 | $headers = @{"Authorization"="Bearer $token"}
234 |
235 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
236 |
237 | return $return
238 | }
239 |
--------------------------------------------------------------------------------
/BoxUser/BoxUser.psm1:
--------------------------------------------------------------------------------
1 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
2 |
3 | # Function to get all users back for an Enterprise
4 | function Get-BoxAllUsers($token)
5 | {
6 | $uri = "https://api.box.com/2.0/users"
7 | $headers = @{"Authorization"="Bearer $token"}
8 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
9 |
10 | #by default, only 100 user are returned. If more groups exist, they must be iterated through in sets of 1000
11 | $totUsers = $return.total_count
12 |
13 | # CAUTION: Adding echo statements for debugging will output to returned result
14 |
15 | if($return.total_count -le $return.limit)
16 | {
17 | return $return.entries
18 | }
19 | else
20 | {
21 | $returned = $return.limit
22 | #$returned = 100000
23 |
24 | $users = $return.entries
25 | while($returned -le $return.total_count)
26 | {
27 | #get the next batch of users
28 | $rd = Get-Date
29 | $uri = "https://api.box.com/2.0/users?limit=1000&offset=$returned"
30 | $more_return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
31 | $users += $more_return.entries
32 | $returned += $more_return.limit
33 | }
34 |
35 | return $users
36 | }
37 | }
38 | # Function to get a Box UserID for a given Box Username
39 | function Get-BoxUserID($username, $token)
40 | {
41 | #returns the Box user id number for a given username
42 | $uri = "https://api.box.com/2.0/users?filter_term=" + $username + "&fields=id"
43 | $headers = @{"Authorization"="Bearer $token"}
44 |
45 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
46 |
47 | if($return.total_count -eq 0){return $null}
48 | else {return $return.entries.id}
49 | }
50 | # Function to get a user object back for a given username
51 | function Get-BoxUser($username, $token)
52 | {
53 | #returns the Box user id number for a given username
54 | $uri = "https://api.box.com/2.0/users?filter_term=" + $username
55 | $headers = @{"Authorization"="Bearer $token"}
56 |
57 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "applicaiton/x-www-form-urlencoded"
58 |
59 | if($return.total_count -eq 0){return $null}
60 | else {return $return.entries}
61 | }
62 | # Function to get a user object back for a given ID
63 | function Get-BoxUser-FromId($id, $token)
64 | {
65 | #returns the Box user information for a given id
66 | $uri = "https://api.box.com/2.0/users/" + $id
67 | $headers = @{"Authorization"="Bearer $token"}
68 |
69 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
70 |
71 | return $return
72 | }
73 |
74 | # Function to create a new user
75 | function New-BoxUser($login, $name, $token)
76 | {
77 | $uri = "https://api.box.com/2.0/users"
78 | $headers = @{"Authorization"="Bearer $token"}
79 |
80 | $json = '{'
81 | $json += '"login": "' + $login + '",'
82 | $json += '"name": "' + $name + '"'
83 | $json += '}'
84 |
85 | $result = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/json"
86 |
87 | return $result.id
88 | }
89 |
90 | # function to remove a Box user
91 | function Remove-BoxUser($id, $token)
92 | {
93 | #sets the given attribute to be the value passed
94 | $uri = "https://api.box.com/2.0/users/" + $id
95 | $headers = @{"Authorization"="Bearer $token"}
96 |
97 | $return = Invoke-RestMethod -Uri $uri -Method Delete -Headers $headers -ContentType "applicaiton/x-www-form-urlencoded"
98 |
99 | return $return
100 | }
101 |
102 | # Function to set an attribute on a user object
103 | function Set-BoxUser($id, $attribute, $value, $token)
104 | {
105 | #sets the given attribute to be the value passed
106 | $uri = "https://api.box.com/2.0/users/" + $id
107 | $headers = @{"Authorization"="Bearer $token"}
108 |
109 | $json = '{ "' + $attribute + '": "' + $value + '"}'
110 |
111 | $return = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -Body $json -ContentType "application/json"
112 |
113 | }
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at devrel@box.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | box-powershell-sdk-v2
7 | =====================
8 |
9 | Windows PowerShell SDK for Box API v2.
10 |
--------------------------------------------------------------------------------
/box/Box.psm1:
--------------------------------------------------------------------------------
1 | ## If you use a proxy, define it here (ie 'http://server.domain.tld:port')
2 | #$PSDefaultParameterValues = @{'Invoke-RestMethod:Proxy' = 'http://server.domain.tld:1234'}
3 |
4 | #set TLS version to 1.2
5 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
6 |
7 | # Group Functions
8 | function New-BoxGroup($token, $name)
9 | {
10 | #create a new Box group with the name given in $name
11 | #returns the groupid
12 |
13 | $uri = "https://api.box.com/2.0/groups"
14 | $headers = @{"Authorization"="Bearer $token"}
15 |
16 | $json = '{"name": "' + $name + '"}'
17 |
18 | $return = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/json"
19 |
20 | return $return.id
21 | }
22 |
23 | function New-BoxGroup2($token, $name)
24 | {
25 | #create a new Box group with the name given in $name
26 | #returns the groupid
27 |
28 | $uri = "https://api.box.com/2.0/groups"
29 | $headers = @{"Authorization"="Bearer $token"}
30 |
31 | $json = '{"name": "' + $name + '","provenance": "MSAD","invitability_level": "all_managed_users","member_viewability_level": "admins_and_members"}'
32 |
33 | $return = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/json"
34 |
35 | return $return.id
36 | }
37 |
38 | function Get-BoxGroup($token, $groupID)
39 | {
40 | $uri = "https://api.box.com/2.0/groups/$($groupID)?fields=provenance,invitability_level,member_viewability_level"
41 | $headers = @{"Authorization"="Bearer $token"}
42 |
43 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
44 |
45 | return $return
46 | }
47 |
48 | function Remove-BoxGroup($token, $groupID)
49 | {
50 | #deletes the given group based on group ID
51 |
52 | $uri = "https://api.box.com/2.0/groups/$groupID"
53 | $headers = @{"Authorization"="Bearer $token"}
54 |
55 | $return = Invoke-RestMethod -Uri $uri -Method Delete -Headers $headers -ContentType "application/x-www-form-urlencoded"
56 | }
57 |
58 | function Add-BoxGroupMember($token, $userID, $groupID)
59 | {
60 | #adds selected member to given group
61 | #return group member detail
62 |
63 | $uri = "https://api.box.com/2.0/group_memberships"
64 | $headers = @{"Authorization"="Bearer $token"}
65 | $json = '{ "user": { "id": "' + $userID + '"}, "group": { "id": "' + $groupID + '" } }'
66 |
67 | $return = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/json"
68 |
69 | }
70 |
71 | function Remove-BoxGroupMember($token, $userID, $groupID)
72 | {
73 | $members = Get-BoxGroupDetails -token $token -groupID $groupID
74 |
75 | for($i = 0; $i -lt $members.Count; $i++)
76 | {
77 | if($members[$i].user.id -eq $userID)
78 | {
79 | $membershipID = $members[$i].id
80 | $i = $members.Count + 1
81 | }
82 | }
83 |
84 | $result = Remove-BoxGroupMembership -token $token -membershipID $membershipID
85 | }
86 |
87 | function Remove-BoxGroupMembership($token, $membershipID)
88 | {
89 | #deletes the given membership based on membership ID
90 |
91 | $uri = "https://api.box.com/2.0/group_memberships/$membershipID"
92 | $headers = @{"Authorization"="Bearer $token"}
93 |
94 | $return = Invoke-RestMethod -Uri $uri -Method Delete -Headers $headers -ContentType "application/x-www-form-urlencoded"
95 | }
96 |
97 | function Get-BoxGroupMembers($groupID, $token)
98 | {
99 | $members = Get-BoxGroupDetails -token $token -groupID $groupID
100 |
101 | $var = @{}
102 |
103 | foreach($member in $members.user)
104 | {
105 | $var.Add($member.login,$member.id)
106 | }
107 |
108 | return $var
109 | }
110 |
111 | function Get-BoxAllGroups($token)
112 | {
113 | $uri = "https://api.box.com/2.0/groups"
114 | $headers = @{"Authorization"="Bearer $token"}
115 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
116 |
117 | #by default, only 100 groups are returned. If more groups exist, they must be iterated through in sets of 1000
118 | if($return.total_count -le $return.limit)
119 | {
120 | return $return.entries
121 | }
122 | else
123 | {
124 | $returned = $return.limit
125 |
126 | $groups = $return.entries
127 |
128 | while($returned -le $return.total_count)
129 | {
130 | #get the next batch of groups
131 | $uri = "https://api.box.com/2.0/groups?limit=1000&offset=$returned"
132 | $more_return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
133 | $groups += $more_return.entries
134 | $returned += $more_return.limit
135 | }
136 | return $groups
137 | }
138 | }
139 |
140 | function Get-BoxGroupDetails($token, $groupID)
141 | {
142 | #input: group id
143 | #output: group details including member list
144 | $uri = "https://api.box.com/2.0/groups/$groupID/memberships"
145 | $headers = @{"Authorization"="Bearer $token"}
146 |
147 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
148 |
149 | return $return.entries
150 | }
151 |
152 | ## User Functions ##
153 |
154 | function Get-BoxAllUsers($token)
155 | {
156 | $uri = "https://api.box.com/2.0/users"
157 | $headers = @{"Authorization"="Bearer $token"}
158 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
159 |
160 | #by default, only 100 groups are returned. If more groups exist, they must be iterated through in sets of 1000
161 | if($return.total_count -le $return.limit)
162 | {
163 | return $return.entries
164 | }
165 | else
166 | {
167 | $returned = $return.limit
168 |
169 | $users = $return.entries
170 |
171 | while($returned -le $return.total_count)
172 | {
173 | #get the next batch of groups
174 | $uri = "https://api.box.com/2.0/users?limit=1000&offset=$returned"
175 | $more_return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
176 | $users += $more_return.entries
177 | $returned += $more_return.limit
178 | }
179 | return $users
180 | }
181 | }
182 |
183 | function Get-BoxUserID($username, $token)
184 | {
185 | #returns the Box user id number for a given username
186 | $uri = "https://api.box.com/2.0/users?filter_term=" + $username + "&fields=id"
187 | $headers = @{"Authorization"="Bearer $token"}
188 |
189 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
190 |
191 | if($return.total_count -eq 0){return $null}
192 | else {return $return.entries.id}
193 | }
194 |
195 | function Get-BoxUser($username, $token)
196 | {
197 | #returns the Box user id number for a given username
198 | $uri = "https://api.box.com/2.0/users?filter_term=" + $username
199 | $headers = @{"Authorization"="Bearer $token"}
200 |
201 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
202 |
203 | if($return.total_count -eq 0){return $null}
204 | else {return $return.entries}
205 | }
206 |
207 | function Set-BoxUser($id, $quota, $token)
208 | {
209 | #sets information about the user. Currently will set the quota. A value of -1 sets it to unlimited. $quota is a value in GB
210 | $uri = "https://api.box.com/2.0/users/" + $id
211 | $headers = @{"Authorization"="Bearer $token"}
212 |
213 | if($quota -ne -1)
214 | {
215 | $quota = $quota * 1073741824
216 | }
217 |
218 | $json = '{ "space_amount": "' + $quota + '"}'
219 |
220 | $return = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -Body $json -ContentType "application/json"
221 |
222 | }
223 |
224 |
225 | ## API Functions ##
226 | function New-BoxoAUTHCode($clientID)
227 | {
228 | $sec_token_sent = "security_token%3DKnhMJatFipTAnM0nHlZA"
229 | $uri = "https://www.box.com/api/oauth2/authorize?response_type=code&client_id=$clientID&state=$sec_token_sent"
230 |
231 | Write-Host "Please visit the URL, authorize the app and note the code value returned."
232 | Write-Host "You have 30 seconds to paste the resulting URL." -ForegroundColor Yellow
233 | Write-Host "The URL is $uri"
234 |
235 | $val = Read-Host "Ready? [Y - launch a browser to URL, N - Do it manually]"
236 | if($val.ToUpper() -eq "Y")
237 | {
238 | Start-Process $uri
239 | }
240 |
241 | $response = Read-Host "Paste return URL."
242 |
243 | $sec_token = $response.Split('=')[1].Substring(0,$response.Split('=')[1].Length - 5)
244 | if($sec_token_sent -ne $sec_token)
245 | {
246 | Write-Host "Warning: Security tokens do not match!" -ForegroundColor Red
247 | }
248 |
249 | return $response.Split('=')[2]
250 | }
251 |
252 | function New-BoxAccessTokens($clientID, $client_secret,$code)
253 | {
254 | $data = "grant_type=authorization_code&code=" + $code + "&client_id=" + $clientID + "&client_secret=" + $client_secret
255 | $uri = "https://www.box.com/api/oauth2/token"
256 |
257 | $json = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/x-www-form-urlencoded" -Body $data
258 |
259 |
260 | $reg_key = "HKLM:\SOFTWARE\BoxAPI"
261 |
262 | if(-not (Test-Path $reg_key))
263 | {
264 | $response = Read-Host "Registry key $reg_key does not exist. Create (requires Administrative rights)? [Y/N]"
265 | if($response.ToUpper() -eq "Y")
266 | {
267 | try{
268 | $reg = New-Item $reg_key -ItemType Registry -Force
269 | }
270 | catch
271 | {
272 | Write-Host "Unable to write to registry."
273 | return $false
274 | }
275 | }
276 | else {return $false}
277 | }
278 |
279 | #write registry entries
280 | $reg = New-ItemProperty -Path $reg_key -Name "access_token" -Value $json.access_token -Force
281 | $reg = New-ItemProperty -Path $reg_key -Name "refresh_token" -Value $json.refresh_token -Force
282 | $reg = New-ItemProperty -Path $reg_key -Name "token_time" -Value (Get-date -Format "yyyy-MM-dd HH:mm:ss") -Force
283 |
284 | return $true
285 | }
286 | function Get-BoxToken($clientID, $client_secret)
287 | {
288 | ## $debug_log can be used to dump verbose information regarding token issues. By default it does not write the debug to the log.
289 |
290 | $debug_log = ""
291 | $reg_key = "HKLM:\SOFTWARE\BoxAPI"
292 |
293 | $last_refresh = Get-ItemProperty -Path $reg_key -Name "token_time"
294 |
295 | $debug_log += "Last refresh time was $($last_refresh.token_time)`r`n"
296 | $debug_log += "Current token is $($(Get-ItemProperty -Path $reg_key -Name "access_token").access_token) `r`n"
297 | $debug_log += "Current refresh token is $($(Get-ItemProperty -Path $reg_key -Name "refresh_token").refresh_token)`r`n"
298 |
299 | #check the last refresh
300 | if(((Get-Date $last_refresh.token_time).AddHours(1)) -le (Get-Date))
301 | {
302 | $debug_log += "Current token is expired - current time is $(Get-Date)`r`n"
303 |
304 | #if the token age is over a hour, we need to refresh
305 | $refresh_token = (Get-ItemProperty -Path $reg_key -Name "refresh_token").refresh_token
306 | $uri = "https://www.box.com/api/oauth2/token”
307 | $data = "grant_type=refresh_token&refresh_token=" + $refresh_token + "&client_id=" + $clientID + "&client_secret=" + $client_secret
308 |
309 | try{
310 | $json = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/x-www-form-urlencoded" -Body $data
311 | }
312 | catch{
313 |
314 | $debug_log += "Error on API call:`r`n$_`r`n"
315 | #$debug_log | Out-File c:\scripts\box\debug.txt -Append
316 |
317 |
318 | return $null
319 | }
320 |
321 | $debug_log += "Query sent. Result:`r`n $json"
322 |
323 | #update registry values
324 | $reg = Set-ItemProperty -Path $reg_key -Name "refresh_token" -Value $json.refresh_token -Force
325 | $reg = Set-ItemProperty -Path $reg_key -Name "token_time" -Value (Get-date -Format "yyyy-MM-dd HH:mm:ss") -Force
326 | $reg = Set-ItemProperty -Path $reg_key -Name "access_token" -Value $json.access_token -Force
327 |
328 | $debug_log += "New refresh time is $($(Get-ItemProperty -Path $reg_key -Name "token_time").token_time)`r`n"
329 | $debug_log += "New token is $($(Get-ItemProperty -Path $reg_key -Name "access_token").access_token)`r`n"
330 | $debug_log += "New refresh token is $($(Get-ItemProperty -Path $reg_key -Name "refresh_token").refresh_token)`r`n"
331 |
332 | #$debug_log | Out-File c:\scripts\box\debug.txt -Append
333 |
334 | return $json.access_token
335 | }
336 | else
337 | {
338 | $debug_log += "Current time is $(Get-Date)`r`n"
339 | $debug_log += "Current token is still valid`r`n"
340 |
341 | #$debug_log | Out-File c:\scripts\box\debug.txt -Append
342 |
343 | #the token is still valid
344 | return (Get-ItemProperty -Path $reg_key -Name "access_token").access_token
345 | }
346 | }
347 |
348 | ## Content Functions ##
349 |
350 | function Get-BoxSubItems($token, $parent)
351 | {
352 | #returns all items in the given parent folder
353 | $uri = "https://api.box.com/2.0/folders/$parent/items"
354 | $headers = @{"Authorization"="Bearer $token"}
355 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "applicaiton/x-www-form-urlencoded"
356 |
357 | if($return.total_count -le $return.limit)
358 | {
359 | return $return.entries
360 | }
361 | else
362 | {
363 | #handle paging when over 1000 entries are returned
364 | $returned = $return.limit
365 |
366 | $folders = $return.entries
367 |
368 | while($returned -le $return.total_count)
369 | {
370 | #get the next page of folders
371 | $uri = "https://api.box.com/2.0/users?limit=1000&offset=$returned"
372 | $more_return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "applicaiton/x-www-form-urlencoded"
373 | $folders += $more_return.entries
374 | $returned += $more_return.limit
375 | }
376 | return $folders
377 | }
378 | }
379 |
380 | function Move-BoxRootFolder($token, $userID, $ownerUserID)
381 | {
382 | $uri = "https://api.box.com/2.0/users/$userID/folders/0?"
383 | $headers = @{"Authorization"="Bearer $token"}
384 |
385 | $json = '{"owned_by": {"id": "' + $ownerUserID + '"}}'
386 |
387 | $return = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -Body $json -ContentType "application/x-www-form-urlencoded"
388 | }
389 |
390 | function Set-BoxFolderName($token, $folderID, $name)
391 | {
392 | #renames the given folder to the given name
393 | $uri = "https://api.box.com/2.0/folders/$folderID"
394 | $headers = @{"Authorization"="Bearer $token"}
395 |
396 | $json = '{"name":"' + $name + '"}'
397 | $return = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -Body $json -ContentType "application/x-www-form-urlencoded"
398 |
399 | return $return
400 | }
401 |
402 | ## Collaboration Functions ##
403 | function New-BoxCollaboration($token, $folderID, $role, $userID)
404 | {
405 | #creates a new collaboration
406 | #possible roles include: owner, editor, viewer, previewer, uploader, previewer uploader, viewer uploader, or co-owner
407 | #returns the collaboration id
408 |
409 | $uri = "https://api.box.com/2.0/collaborations"
410 | $headers = @{"Authorization"="Bearer $token"}
411 |
412 | $json = '{"item":{"id":"' + $folderID + '","type":"folder"},"accessible_by":{"id":"' + $userID + '","type":"user"},"role":"' + $role + '"}'
413 |
414 | $return = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $json -ContentType "application/x-www-form-urlencoded"
415 |
416 | return $return.id
417 | }
418 |
419 | function Set-BoxCollaboration($token, $collabID, $role)
420 | {
421 | $uri = "https://api.box.com/2.0/collaborations/$collabID"
422 | $headers = @{"Authorization"="Bearer $token"}
423 |
424 | $json = '{"role":"' + $role + '"}'
425 |
426 | try{
427 | $return = Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -Body $json -ContentType "application/x-www-form-urlencoded"
428 | }
429 | catch{
430 | $return = $null
431 | }
432 | return $return
433 | }
434 |
435 | function Get-BoxFolderCollab($token, $folderID)
436 | {
437 | #returns the collaborations on the given folder
438 |
439 | $uri = "https://api.box.com/2.0/folders/$folderID/collaborations"
440 | $headers = @{"Authorization"="Bearer $token"}
441 |
442 | $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ContentType "application/x-www-form-urlencoded"
443 |
444 | return $return
445 | }
446 |
447 | function Remove-BoxCollaborator($token, $collabID)
448 | {
449 | #removes the collaboration ID
450 | $headers = @{"Authorization"="Bearer $token"}
451 |
452 | $uri = "https://api.box.com/2.0/collaborations/$collabID"
453 | $return = Invoke-RestMethod -Uri $uri -Method Delete -Headers $headers -ContentType "application/x-www-form-urlencoded"
454 |
455 | return $return
456 | }
457 |
458 | # Custom Objects
459 | $BoxScope = New-Object PSObject
460 | $BoxScope | Add-Member -NotePropertyName admins -NotePropertyValue admins_only
461 | $BoxScope | Add-Member -NotePropertyName members -NotePropertyValue admins_and_members
462 | $BoxScope | Add-Member -NotePropertyName all -NotePropertyValue all_managed_users
463 |
--------------------------------------------------------------------------------
/images/box-dev-logo-clip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/box-community/sdk-powershell-api-v2/b3804e37f67d81aee5d4989ed8241724a79e0b66/images/box-dev-logo-clip.png
--------------------------------------------------------------------------------
/samples/GenerateAccessTokens.ps1:
--------------------------------------------------------------------------------
1 | # This script will aquire a new authorization code and access tokens. This will launch a browser
2 | # and request that you authorize your app to grant the oAuth code. This must happen quickly due
3 | # to timeouts (30 seconds). Paste the return URL in the powershell windows when prompted and
4 | # the tokens will be aquired using the code and stored in the registry. Creating the registry
5 | # keys will require the script be run as an administrator.
6 |
7 |
8 | $c_id = ""
9 | $c_secret = ""
10 |
11 | $code = New-BoxoAUTHCode -clientID $c_id
12 |
13 | New-BoxAccessTokens -clientID $c_id -client_secret $c_secret -code $code
--------------------------------------------------------------------------------
/samples/GetUsersFromBox.ps1:
--------------------------------------------------------------------------------
1 | # GetUsersFromBox.ps1
2 | #
3 | # Get all users from box into a CSV for import processing
4 |
5 | ##edit below this line##
6 |
7 | $outputFile = "C:\box_user_list.dat"
8 | $rundate = Get-Date
9 | $ClientID = "your-client-id"
10 | $ClientSecret = "your-client-secret"
11 | #add the PSModulePath where the PSM files exist for the project
12 | $env:PSModulePath = $env:PSModulePath + ";c:\box-powershell-sdk-v2"
13 |
14 | ##edit above this line##
15 |
16 | #Import Box modules
17 | Echo "-- Importing Module Box Auth --"
18 | ipmo BoxAuth
19 | Echo "-- Importing Module Box User --"
20 | ipmo BoxUser
21 |
22 | Echo "-- Starting to get data from box.com via API on: $rundate --"
23 |
24 | try{ $token = Get-BoxToken $ClientID $ClientSecret
25 | }
26 | catch{
27 | write-host "Error getting a token from Box - $_"
28 | Exit 1
29 | }
30 |
31 | try { $users = Get-BoxAllUsers($token)
32 | }
33 | catch {
34 | write-host "Error getting all users from Box - $_"
35 | Exit 1
36 | }
37 |
38 | try {
39 | $users | Select-Object "id","name","login","space_amount","type","can_see_managed_users","is_sync_enabled","status" | Export-Csv -NoTypeInformation $outputFile
40 | }
41 | catch {
42 | write-host "Error getting all users exported to the csv - $_"
43 | Exit 1
44 | }
45 |
46 | $rundate = Get-Date
47 | echo "-- Finished getting data from Box.com at $rundate --"
--------------------------------------------------------------------------------
/samples/SetQuota.ps1:
--------------------------------------------------------------------------------
1 | # SetQuota.ps1
2 | #
3 | # This will set all users within a Box tenant to have an unlimited quota
4 |
5 |
6 | ## Edit below this line before use ##
7 |
8 | $c_id = "" #replace with your client id
9 | $c_secret = "" #replace with your client secret
10 |
11 | Import-Module C:\Box\Box.psm1 #replace with the path to Box.psm1
12 |
13 | $quota = -1 #set to desired quota in bytes. -1 sets a user to unlimited
14 |
15 | ## Edit above this line before use ##
16 |
17 | $dev_token = Get-BoxToken -clientID $c_id -client_secret $c_secret
18 |
19 | $users = Get-BoxAllUsers -token $dev_token
20 |
21 | foreach($user in $users)
22 | {
23 | Set-BoxUser -id $user.id -quota $quota -token $dev_token
24 | }
25 |
--------------------------------------------------------------------------------
/samples/SetQuota2.ps1:
--------------------------------------------------------------------------------
1 | # SetQuota2.ps1 - using attribute based solution + secure directory credentials
2 | #
3 | # This will set all users within a Box tenant to have an unlimited quota
4 |
5 | ## Edit below this line before use ##
6 | $c_id = "" #replace with your client id
7 | $c_secret = "" #replace with your client secret
8 | $s_dir = "" #set secure directory
9 | $attribute = "quota" # attribute to be adjusted
10 | $value = -1 #set to desired value, for quota in bytes. -1 sets a user to unlimited quota
11 |
12 | #add the PSModulePath where the PSM files exist for the project
13 | $env:PSModulePath = $env:PSModulePath + ";c:\box-powershell-sdk-v2"
14 |
15 | ## Edit above this line before use ##
16 |
17 | Echo "-- Importing Module Box Auth --"
18 | ipmo BoxAuth
19 | Echo "-- Importing Module Box User --"
20 | ipmo BoxUser
21 |
22 | $dev_token = Get-BoxToken -clientID $c_id -client_secret $c_secret -secure_dir $s_dir
23 |
24 | $users = Get-BoxAllUsers -token $dev_token
25 |
26 | foreach($user in $users)
27 | {
28 | Set-BoxUser -id $user.id -attribute $attribute -value $value -token $dev_token
29 | }
30 |
--------------------------------------------------------------------------------
/samples/syncADgroups.ps1:
--------------------------------------------------------------------------------
1 | function Get-UADGroups()
2 | {
3 | $parent = Get-ADGroup BoxSyncedGroups #Looks for the Active Directory group named BoxSyncedGroups
4 | $members = Get-ADGroupMember $parent | where {$_.whenChanged -ge $(Get-LastRunTime)} #finds all member groups
5 |
6 | return $members
7 | }
8 |
9 | function Get-UADGroupMembers($name)
10 | {
11 | $username = @()
12 | $admembers = (Get-ADGroupMember $name).name
13 | return $admembers
14 | }
15 |
16 | function New-GroupHashfromAD($groups)
17 | {
18 | $new_hash = @{}
19 |
20 | #adds each group in AD to a hash table that contains the group SID
21 | foreach($group in $groups)
22 | {
23 | $new_hash.Add($group.name,$group.SID.Value)
24 | }
25 | return $new_hash
26 | }
27 |
28 | function New-GroupHashfromBox($groups)
29 | {
30 | $new_hash = @{}
31 |
32 | #adds each group in Box to a hash table that contains the group id
33 | foreach($group in $groups)
34 | {
35 | $new_hash.Add($group.name,$group.id)
36 | }
37 | return $new_hash
38 | }
39 | function New-GroupMemberHashFromBox($group){
40 | $new_hash = @{}
41 | foreach($member in $group)
42 | {
43 | $new_hash.Add($member.user.login,$member.user.id)
44 | }
45 | return $new_hash
46 | }
47 | function New-UserHashfromBox($users)
48 | {
49 | $new_hash = @{}
50 |
51 | #create a hash table of all users in Box and their id's
52 | foreach($user in $users)
53 | {
54 | $new_hash.Add($user.login,$user.id)
55 | }
56 | return $new_hash
57 | }
58 | function Get-LastRunTime()
59 | {
60 | #this will return the last run of the sync process
61 | return (Get-ScheduledTaskInfo -TaskName "Temp Test Task").lastruntime
62 | }
63 |
64 |
65 | function SyncBoxGroups($token)
66 | {
67 | $log = ""
68 |
69 | #check to see if the AD group has been modified since last script run
70 | $modifiedDate = $(Get-ADGroup BoxSyncedGroups -Properties @("whenChanged")).whenChanged
71 |
72 | if($(Get-ADGroup BoxSyncedGroups -Properties @("whenChanged")).whenChanged -gt $(Get-LastRunTime))
73 | {
74 | #the AD group has been modified since the last run, sync groups
75 |
76 | $adgroups = Get-UADGroups #returns all AD groups that should be synced
77 | $boxgroups = Get-BoxAllGroups -token $dev_token #returns all existing groups in Box using Box Powershell SDK v2
78 |
79 | $adHash = New-GroupHashfromAD($adgroups) #builds a hash table of all identified AD groups and their corresponding SIDs
80 | $boxHash = New-GroupHashfromBox($boxgroups) #builds a hash table of all identified Box groups and their corresponding id's
81 |
82 | # build the list of groups in AD but not Box
83 | $addList = @()
84 |
85 | foreach($group in @($adHash.keys))
86 | {
87 | if(-not $boxHash.Contains($group))
88 | {
89 | $addList += $group
90 | }
91 | }
92 |
93 | $log += "Found $($addList.count) groups to create in Box.`r`n"
94 |
95 | #build the list of groups in Box but not AD
96 | $delList = @()
97 |
98 | foreach($group in @($boxHash.keys))
99 | {
100 | if(-not $adHash.Contains($group))
101 | {
102 | $delList += $group
103 | }
104 | }
105 |
106 | $log += "Found $($delList.count) groups to delete in Box.`r`n"
107 |
108 | #add missing groups to Box
109 | foreach($group in $addList)
110 | {
111 | $log += "Creating group $group in Box..."
112 | $gid = New-BoxGroup -token $dev_token -name $group #create a new group in Box using the Box Powershell SDK v2
113 | $log += "Done!`r`n"
114 | }
115 |
116 | #remove groups from Box that are not in AD
117 | foreach($group in $delList)
118 | {
119 | $log += "Deleting group $group from Box..."
120 | Remove-BoxGroup -token $dev_token -groupID $boxHash[$group] #delete the Box group using the Box Powershell SDK v2
121 | $log += "Done!`r`n"
122 | }
123 |
124 | }
125 | else
126 | {
127 | $log += "No changes since last run - not syncing groups.`r`n"
128 | }
129 |
130 | return $log
131 | }
132 |
133 | function SyncBoxGroupMembers($token)
134 | {
135 | $adgroups = Get-UADGroups #returns all AD groups that should be synced
136 |
137 | if($adgroups -ne $null)
138 | {
139 | $adHash = New-GroupHashfromAD($adgroups) #build a hash table of the returned groups and their SID's
140 |
141 | $total = 0
142 | $boxusers = Get-BoxAllUsers -token $dev_token #return all users in Box using the Box Powershell SDK v2
143 | $boxuserhash = New-UserHashfromBox -users $boxusers #build a hash table of the returned users and their id's
144 |
145 | $boxgroups = Get-BoxAllGroups -token $dev_token #return all groups in Box using the Box Powershell SDK v2
146 | $boxHash = New-GroupHashfromBox($boxgroups) #build a hash table of the returned groups and their id's
147 |
148 | $log += "Beginning group membership update...`r`n"
149 |
150 | #iterate through each AD group
151 | foreach($adgroup in @($adHash.Keys))
152 | {
153 | $log += "Updating membership of $adgroup.`r`n"
154 |
155 | $boxmembers = Get-BoxGroupDetails -token $token -groupID $boxHash[$adgroup]
156 | $admembers = (Get-ADGroupMember $adgroup -Recursive).samaccountname
157 |
158 | $boxGroupID = $boxHash[$adgroup]
159 |
160 | $boxmemberhash = New-GroupMemberHashFromBox -group $boxmembers
161 |
162 | ## get list of users to add
163 | $addList = @()
164 |
165 | foreach($user in $admembers)
166 | {
167 | $login = $user + "@"
168 | if(-not $boxmemberhash.Contains($login))
169 | {
170 | $addList += $login
171 | }
172 | }
173 | $log += "$($addList.Count) members to add to group $adgroup.`r`n"
174 |
175 | #get list of users to delete
176 | $delList = @{}
177 |
178 | foreach($user in @($boxmemberhash.Keys))
179 | {
180 | $account = $user.Substring(0,$user.IndexOf('@'))
181 | if(-not $admembers.Contains($account.ToUpper()))
182 | {
183 | $delList.Add($user,$boxmemberhash[$user])
184 | }
185 | }
186 | $log += "$($delList.Count) members to remove from group $adgroup.`r`n"
187 |
188 | #add users to Box group
189 | foreach($user in $addList)
190 | {
191 | #only add the user if they exist in Box, otherwise, skip
192 | if($boxuserhash.Contains($user))
193 | {
194 | #add to group
195 | $add = Add-BoxGroupMember -token $token -groupID $boxGroupID -userID $boxuserhash[$user]
196 | $log += "$user added to Box group $adgroup.`r`n"
197 | }
198 | else
199 | {
200 | $log += "$user not found in Box, cannot add to $adgroup.`r`n"
201 | }
202 | }
203 |
204 | #delete users from Box group
205 | foreach($username in @($delList.Keys))
206 | {
207 | Remove-BoxGroupMember -token $token -userID $delList[$username] -groupID $boxGroupID
208 | $log += "$username removed from Box group $adgroup.`r`n"
209 | }
210 | $total++
211 | }
212 |
213 | $log += "Done! Updated $($adhash.count) groups.`r`n"
214 | }
215 | else
216 | {
217 | $log += "No changes to group memberships - nothing to update.`r`n"
218 | }
219 |
220 | return $log
221 | }
222 |
223 | $start = Get-date #used for log tracking
224 |
225 | $clientID = "" #put your clientID here
226 | $secret = "" #put your client secret here
227 |
228 | $dev_token = Get-BoxToken -clientID $clientID -client_secret $secret #use Box Powershell SDK to get a valid token
229 |
230 | $log = "Start time: $start`r`n"
231 |
232 | ### Add/Remove the groups in Box ###
233 | # Assumes all groups to sync are contained in an Active Directory group BoxSyncedGroups
234 | $log += SyncBoxGroups -token $dev_token
235 | # at this point the identified groups in AD now exist in Box - no more or less
236 |
237 | ## Update group memberships
238 | $log += SyncBoxGroupMembers -token $dev_token
239 | # at this point the identified groups in AD have a synced membership in Box
240 |
241 | $end = Get-date
242 | $log +="End time: $end`r`n"
243 |
244 | $log | Out-File boxgroupsync.txt -Append #append to logfile boxgroupsync.txt
245 |
--------------------------------------------------------------------------------