Compare commits
No commits in common. "96368d0c7c74ac71f00c62b34884f5a9dbe54106" and "375354b609491b00af3b520484d125b86655a872" have entirely different histories.
96368d0c7c
...
375354b609
@ -1,234 +0,0 @@
|
||||
|
||||
#region Private Helpers
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Tests if a PnP Group exists.
|
||||
.DESCRIPTION
|
||||
This function tests if a PnP Group exists in the current SharePoint site.
|
||||
.PARAMETER Identity
|
||||
The identity of the group to test.
|
||||
.EXAMPLE
|
||||
Test-PnPGroup -Identity "MyGroup"
|
||||
#>
|
||||
function Test-PnPGroup {
|
||||
param(
|
||||
[string]$Identity
|
||||
)
|
||||
|
||||
try {
|
||||
Get-PnPGroup -Identity $Identity -ErrorAction Stop | Out-Null
|
||||
return $true
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Tests if an Entra ID Group exists and PnP can resolve it.
|
||||
.DESCRIPTION
|
||||
This function tests if a Entra ID Group exists and can be resolved by PnP.
|
||||
.PARAMETER Identity
|
||||
The identity of the group to test.
|
||||
.EXAMPLE
|
||||
Test-EntraIdGroup -Identity "MyGroup"
|
||||
#>
|
||||
function Test-EntraIdGroup {
|
||||
param(
|
||||
[string]$Identity
|
||||
)
|
||||
|
||||
try {
|
||||
Get-PnPEntraIdGroup -Identity $Identity -ErrorAction Stop | Out-Null
|
||||
return $true
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Functions
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Sets permissions on a folder in a SharePoint document library.
|
||||
.DESCRIPTION
|
||||
This script breaks permission inheritance on a specified folder in a SharePoint document library and assigns permissions to a specified owner group and additional groups defined in the ACL parameter.
|
||||
.PARAMETER Name
|
||||
The name of the folder to set permissions on.
|
||||
.PARAMETER List
|
||||
The name of the document library containing the folder. Default is 'Shared Documents'.
|
||||
.PARAMETER Owner
|
||||
The name of the SharePoint group to assign as the owner of the folder with 'Full Control' permissions.
|
||||
.PARAMETER Acl
|
||||
An array of objects defining additional groups and their permissions to assign to the folder. Each object should have a 'DisplayName' property for the group name and a 'Role' property for the permission level (e.g., 'Read', 'Edit').
|
||||
.EXAMPLE
|
||||
$Acl = @(
|
||||
@{ DisplayName = "SG-ADMIN-AdvocateFloats-Dynamic"; Role = "Edit" },
|
||||
@{ DisplayName = "SG-ADMIN-AdvocateManagers-Dynamic"; Role = "Edit" }
|
||||
)
|
||||
.\Set-PnPFolderAcl.ps1 -Name "ProjectX" -List "Shared Documents" -Owner "Project Owners" -Acl $Acl
|
||||
#>
|
||||
function Set-PnPFolderAcl {
|
||||
[CmdletBinding(
|
||||
SupportsShouldProcess = $true,
|
||||
ConfirmImpact = 'High'
|
||||
)]
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory,
|
||||
ValueFromPipeline,
|
||||
ValueFromPipelineByPropertyName
|
||||
)]
|
||||
[string]$FolderName,
|
||||
|
||||
[Parameter()]
|
||||
[string]$List = 'Shared Documents',
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string]$Owner,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[pscustomobject[]]$Acl
|
||||
)
|
||||
|
||||
begin {
|
||||
if (-not (Get-PnPContext)) {
|
||||
Throw "Not connected to a SharePoint site. Run Connect-PnPOnline first."
|
||||
}
|
||||
|
||||
if (-not (Get-PnPList -Identity $List -ErrorAction SilentlyContinue)) {
|
||||
Throw "The specified list '$List' does not exist."
|
||||
}
|
||||
|
||||
if (-not (Test-PnPGroup -Identity $Owner)) {
|
||||
Throw "The specified owner group '$Owner' does not exist."
|
||||
}
|
||||
|
||||
$ValidRoles = Get-PnPRoleDefinition | Select-Object -ExpandProperty Name
|
||||
|
||||
if (-not $ValidRoles) {
|
||||
throw "Unable to retrieve SharePoint role definitions."
|
||||
}
|
||||
|
||||
|
||||
foreach ($entry in $Acl) {
|
||||
if (-not ($entry.PSObject.Properties.Name -contains 'Group' -and
|
||||
$entry.PSObject.Properties.Name -contains 'Role')) {
|
||||
Throw "Each ACL entry must contain 'Group' and 'Role' properties."
|
||||
}
|
||||
if (-not (Test-PnPGroup -Identity $entry.Group) -and
|
||||
-not (Test-EntraIdGroup -Identity $entry.Group)) {
|
||||
Throw "The specified group '$($entry.Group)' does not exist as a PnP Group or Entra ID Group."
|
||||
}
|
||||
if ($entry.Role -notin $ValidRoles) {
|
||||
Throw "Invalid role '$($entry.Role)' specified for group '$($entry.Group)'. Valid roles are: $($ValidRoles -join ', ')."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
$FolderPath = "$List/$FolderName"
|
||||
|
||||
# Retrieve folder and current permissions
|
||||
$FolderItem = Get-PnPFolder -Url $FolderPath -ErrorAction Stop
|
||||
$ListItem = Get-PnPListItem -List $List -Id $FolderItem.ListItemAllFields.Id
|
||||
|
||||
|
||||
# Break inheritance ONLY IF the folder doesn't already have unique permissions
|
||||
if (-not $ListItem.HasUniqueRoleAssignments) {
|
||||
|
||||
if ($PSCmdlet.ShouldProcess(
|
||||
$FolderPath,
|
||||
"Break inheritance and grant Full Control to '$Owner' on '$FolderPath'."
|
||||
)) {
|
||||
|
||||
Write-Verbose "Breaking inheritance for '$FolderPath'."
|
||||
Write-Verbose "Granting 'Full Control' to '$Owner' on '$FolderPath'."
|
||||
|
||||
Set-PnPFolderPermission `
|
||||
-List $List `
|
||||
-Identity $FolderPath `
|
||||
-Group $Owner `
|
||||
-AddRole 'Full Control' `
|
||||
-ClearExisting
|
||||
}
|
||||
}
|
||||
|
||||
# Get existing role assignments
|
||||
$RoleAssignments = Get-PnPProperty -ClientObject $ListItem -Property RoleAssignments
|
||||
|
||||
$CurrentAcl = foreach ($ra in $RoleAssignments) {
|
||||
$principal = Get-PnPProperty -ClientObject $ra -Property Member
|
||||
$bindings = Get-PnPProperty -ClientObject $ra -Property RoleDefinitionBindings
|
||||
|
||||
foreach ($binding in $bindings) {
|
||||
[pscustomobject]@{
|
||||
Principal = $principal.Title
|
||||
Role = $binding.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# foreach ($entry in $CurrentAcl) {
|
||||
|
||||
# if ($entry.Principal -eq $Owner) {
|
||||
# continue
|
||||
# }
|
||||
|
||||
# if
|
||||
# }
|
||||
|
||||
foreach ($entry in $Acl) {
|
||||
|
||||
$GroupName = $entry.Group
|
||||
$Role = $entry.Role
|
||||
|
||||
$AlreadyAssigned = $ResolvedRoles | Where-Object {
|
||||
$_.Principal -eq $GroupName -and
|
||||
$_.Role -eq $Role
|
||||
}
|
||||
|
||||
if ($AlreadyAssigned) {
|
||||
Write-Verbose "Permission '$Role' already assigned to '$GroupName' on '$FolderPath'. Skipping."
|
||||
continue
|
||||
}
|
||||
|
||||
if (Test-PnPGroup $GroupName) {
|
||||
if ($PSCmdlet.ShouldProcess(
|
||||
$FolderPath,
|
||||
"Grant '$Role' to SharePoint group '$GroupName' on '$FolderPath'."
|
||||
)) {
|
||||
|
||||
Write-Verbose "Granting '$Role' to SharePoint group '$GroupName' on '$FolderPath'."
|
||||
|
||||
Set-PnPFolderPermission `
|
||||
-List $List `
|
||||
-Identity $FolderPath `
|
||||
-Group $GroupName `
|
||||
-AddRole $Role
|
||||
}
|
||||
} elseif (Test-EntraIdGroup $GroupName) {
|
||||
if ($PSCmdlet.ShouldProcess(
|
||||
$FolderPath,
|
||||
"Grant '$Role' to Entra ID group '$GroupName' on '$FolderPath'."
|
||||
)) {
|
||||
|
||||
Write-Verbose "Granting '$Role' to Entra ID group '$GroupName' on '$FolderPath'."
|
||||
|
||||
Set-PnPFolderPermission `
|
||||
-List $List `
|
||||
-Identity $FolderPath `
|
||||
-Group $GroupName `
|
||||
-AddRole $Role
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Export-ModuleMember -Function Set-PnPFolderAcl
|
||||
@ -1,33 +0,0 @@
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$UserId
|
||||
)
|
||||
|
||||
$VerbosePreference = 'Continue'
|
||||
|
||||
Connect-MgGraph -NoWelcome -Scopes User.ReadWrite.All,Organization.Read.All
|
||||
|
||||
$User = Get-MgUser -UserId $UserId -Property DisplayName,UserPrincipalName,Id,OnPremisesImmutableId | Select-Object -Property DisplayName,UserPrincipalName,Id,OnPremisesImmutableId
|
||||
|
||||
Write-Host "User identified to remove is '$($User.DisplayName) ($($User.UserPrincipalName))'"
|
||||
do {
|
||||
$Decision = Read-Host "Continue? (y/n)"
|
||||
if ($Decision -cmatch '[Nn](?:o)?') { exit }
|
||||
} while ($Decision -cnotmatch '[Yy](?:es)?')
|
||||
|
||||
Write-Host "Removing OnPremisesImmutableId..."
|
||||
Invoke-MgGraphRequest -Method PATCH -Uri "https://graph.microsoft.com/v1.0/Users/$($User.Id)" -Body @{OnPremisesImmutableId = $null}
|
||||
Write-Verbose "OnPremisesImmutableId: '$($User.OnPremisesImmutableId)' -> '$((Get-MgUser -UserId $UserId -Property OnPremisesImmutableId).OnPremisesImmutableId)'"
|
||||
|
||||
Write-Host "Starting ADSync Delta sync... " -NoNewline
|
||||
try {
|
||||
if ($Configuration.RemoteAdSync) {
|
||||
Invoke-Command -ComputerName $Configuration.RemoteAdSyncComputerName -ScriptBlock { (Start-AdSyncSyncCycle -PolicyType Delta).Result }
|
||||
} else {
|
||||
(Start-AdSyncSyncCycle -PolicyType Delta).Result
|
||||
}
|
||||
} catch {
|
||||
Write-Host -ForegroundColor Red "Failed: $_"
|
||||
break
|
||||
}
|
||||
@ -1,107 +0,0 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Replaces a license for Microsoft 365 users.
|
||||
.DESCRIPTION
|
||||
This script replaces a specified license (SKU) with another license for Microsoft 365 users.
|
||||
.PARAMETER InputObject
|
||||
The Microsoft Graph user objects to process.
|
||||
.PARAMETER RemoveSkuPartNumber
|
||||
The SKU Part Number of the license to be removed.
|
||||
.PARAMETER RemoveSkuId
|
||||
The SKU Id of the license to be removed.
|
||||
.PARAMETER AddSkuPartNumber
|
||||
The SKU Part Number of the license to be added.
|
||||
.PARAMETER AddSkuId
|
||||
The SKU Id of the license to be added.
|
||||
.PARAMETER All
|
||||
If specified, all users with the license to be removed will be processed.
|
||||
.PARAMETER WhatIf
|
||||
If specified, the actions will be displayed without making any changes.
|
||||
#>
|
||||
function Set-License {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
[array]
|
||||
$InputObject,
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName='SkuPartNumber')]
|
||||
[string]
|
||||
$RemoveSkuPartNumber,
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName='SkuId')]
|
||||
[guid]
|
||||
$RemoveSkuId,
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName='SkuPartNumber')]
|
||||
[string]
|
||||
$AddSkuPartNumber,
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName='SkuId')]
|
||||
[guid]
|
||||
$AddSkuId,
|
||||
[Parameter()]
|
||||
[switch]
|
||||
$All,
|
||||
[Parameter()]
|
||||
[switch]
|
||||
$WhatIf
|
||||
)
|
||||
|
||||
begin {
|
||||
if ($null -eq (Get-MgContext)) {
|
||||
throw 'You are not connected to Microsoft Graph. Please connect using Connect-MgGraph.'
|
||||
}
|
||||
|
||||
if ($PSCmdlet.ParameterSetName -eq 'SkuPartNumber') {
|
||||
# Validate that the Remove SKU exists and get its Id
|
||||
$RemoveSku = (Get-MgSubscribedSku -All | Where-Object { $_.SkuPartNumber -eq $RemoveSkuPartNumber })
|
||||
if ($null -eq $RemoveSku) {
|
||||
throw "The SKU Part Number '$RemoveSkuPartNumber' was not found."
|
||||
}
|
||||
$RemoveSkuId = $RemoveSku.SkuId
|
||||
|
||||
# Validate that the Add SKU exists and get its Id
|
||||
$AddSku = (Get-MgSubscribedSku -All | Where-Object { $_.SkuPartNumber -eq $AddSkuPartNumber })
|
||||
if ($null -eq $AddSku) {
|
||||
throw "The SKU Part Number '$AddSkuPartNumber' was not found."
|
||||
}
|
||||
$AddSkuId = $AddSku.SkuId
|
||||
} elseif ($PSCmdlet.ParameterSetName -eq 'SkuId') {
|
||||
# Validate that the Remove SKU exists
|
||||
$RemoveSku = (Get-MgSubscribedSku -All | Where-Object { $_.SkuId -eq $RemoveSkuId })
|
||||
if ($null -eq $RemoveSku) {
|
||||
throw "The SKU Id '$RemoveSkuId' was not found."
|
||||
}
|
||||
|
||||
# Validate that the Add SKU exists
|
||||
$AddSku = (Get-MgSubscribedSku -All | Where-Object { $_.SkuId -eq $AddSkuId })
|
||||
if ($null -eq $AddSku) {
|
||||
throw "The SKU Id '$AddSkuId' was not found."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
$Users = @()
|
||||
if ($All) {
|
||||
# Get all users with the old SKU assigned
|
||||
$Users = Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $RemoveSkuId)" -All
|
||||
} else {
|
||||
# Get users from the pipeline with the old SKU assigned
|
||||
$Users += (Get-MgUser -UserId $InputObject.Id -Property Id,DisplayName,UserPrincipalName,AssignedLicenses) | Where-Object { $RemoveSkuId -in $_.AssignedLicenses.SkuId }
|
||||
}
|
||||
|
||||
foreach ($User in $Users) {
|
||||
if ($WhatIf) {
|
||||
Write-Host "WhatIf: Replacing license for user '$($User.UserPrincipalName)' - Removing SKU Id '$RemoveSkuId', Adding SKU Id '$AddSkuId'"
|
||||
} else {
|
||||
# Replace the license
|
||||
Set-MgUserLicense -UserId $User.Id -RemoveLicenses @($RemoveSkuId) -AddLicenses @{}
|
||||
Set-MgUserLicense -UserId $User.Id -RemoveLicenses @() -AddLicenses @{ SkuId = $AddSkuId }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Set-License
|
||||
@ -99,4 +99,4 @@ foreach ($User in $Users) {
|
||||
}
|
||||
|
||||
# $Results | sort OfficeLocation,DisplayName | select Id,DisplayName,License,JobTitle,@{Label='BusinessPhone';Expression={$_.BusinessPhones[0]}},MobilePhone,FaxNumber,CompanyName,OfficeLocation | Out-GridView
|
||||
$Results | Sort-Object OfficeLocation,DisplayName | Select-Object Id,DisplayName,License,JobTitle,OfficeLocation,CompanyName,Department,@{Label='BusinessPhone';Expression={$_.BusinessPhones[0]}},MobilePhone,FaxNumber | Export-Csv -Path results.csv -NoTypeInformation
|
||||
$Results | Sort-Object OfficeLocation,DisplayName | Select-Object Id,DisplayName,License,JobTitle,@{Label='BusinessPhone';Expression={$_.BusinessPhones[0]}},MobilePhone,FaxNumber,CompanyName,OfficeLocation | Export-Csv -Path results.csv -NoTypeInformation
|
||||
@ -1,16 +0,0 @@
|
||||
$Username = ((Get-CimInstance win32_computersystem | ForEach-Object username) -split '\\')[1]
|
||||
Write-Host "Signed in user is '$Username'"
|
||||
|
||||
# Map PSDrive for HKU
|
||||
New-PSDrive -Name HKU -PSProvider Registry -Root hkey_users | Out-Null
|
||||
|
||||
# Find matching Volatile Env
|
||||
try {
|
||||
$Environment = ((Get-ItemProperty 'HKU:\*\Volatile Environment' | Where-Object Username -eq $Username).PSPath -split '\\')[2]
|
||||
$UserRegistryPath = Join-Path -Path 'HKU:' -ChildPath $Environment
|
||||
} catch [System.Security.SecurityException] {
|
||||
Write-Error "Permission Denied"
|
||||
throw System.Security.SecurityException
|
||||
}
|
||||
|
||||
Write-Host "User registry path is '$UserRegistryPath'"
|
||||
@ -6,8 +6,8 @@ $TenantId = ''
|
||||
$CompanyId = ''
|
||||
$UserSecret = ''
|
||||
|
||||
$AgentInstallUrl = (Invoke-RestMethod -Method "Get" -URI "https://configuration.myconnectsecure.com/api/v4/configuration/agentlink?ostype=windows")
|
||||
$AgentInstallFile = 'cybercnsagent.exe'
|
||||
$AgentInstallUrl = (Invoke-RestMethod -Method "Get" -URI "https://configuration.myconnectsecure.com/api/v4/configuration/agentlink?ostype=windows&msi_required=true")
|
||||
$AgentInstallFile = 'cybercnsagent.msi'
|
||||
$AgentInstallPath = Join-Path -Path $PackagesPath -ChildPath $AgentInstallFile
|
||||
|
||||
# Prep
|
||||
@ -24,9 +24,8 @@ Write-Host "Downloading agent installer..."
|
||||
# Install
|
||||
|
||||
Write-Host "Starting installation..."
|
||||
Start-Process -FilePath $AgentInstallPath -ArgumentList "-c $($CompanyId) -e $TenantId -j $UserSecret -i" -Wait
|
||||
#Start-Process msiexec -ArgumentList "/i `"$AgentInstallPath`" /q WRAPPED_ARGUMENTS=`"-c $CompanyId -e $TenantId -j $UserSecret -i`" /lv `"$($AgentInstallPath).log`"" -Wait
|
||||
#Write-Host "Log saved at $($AgentInstallPath).log"
|
||||
Start-Process msiexec -ArgumentList "/i `"$AgentInstallPath`" /q WRAPPED_ARGUMENTS=`"-c $CompanyId -e $TenantId -j $UserSecret -i`" /lv `"$($AgentInstallPath).log`"" -Wait
|
||||
Write-Host "Log saved at $($AgentInstallPath).log"
|
||||
|
||||
# Clean up
|
||||
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
$PackagesPath = 'C:\Packages'
|
||||
$DestinationPath = 'C:\Program Files\nssm'
|
||||
|
||||
$InstallerUrl = 'https://nssm.cc/release/nssm-2.24.zip'
|
||||
$InstallerUrl = 'https://nssm.cc/ci/nssm-2.24-103-gdee49fc.zip'
|
||||
|
||||
$ArchivePath = Join-Path -Path $PackagesPath -ChildPath ($InstallerUrl | Select-String -Pattern "(nssm-(?:\d\.?)+\.zip)").Matches.Value
|
||||
$ArchivePath = Join-Path -Path $PackagesPath -ChildPath ($InstallerUrl | Select-String -Pattern "(nssm-(?:\d\.?)+-\d.*\.zip)").Matches.Value
|
||||
|
||||
# Exit if the application is already installed
|
||||
if (Test-Path $DestinationPath) { Write-Host 'NSSM is already installed.'; exit }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user