UsersToDevices.psm1
function Add-User-Devices { <# .SYNOPSIS Finds registered devices of users in UserGroup and adds them into DeviceGroup. .DESCRIPTION Author: David Velasquez Dependencies: AzureAD Module NuGet provider version '2.8.5.201' or newer Optional Dependency: ImportExcel Module Accepts [-Excel] as optional parameter to generate an excel spreadsheet report. Accepts [-Mobile] as optional parameter to only add mobile devices to [-DeviceGroup]. Accepts [-E] and [-M] as parameter aliases for [-Excel] and [-Mobile]. Accepts [-From] and [-To] as parameter aliases for [-UserGroup] and [-DeviceGroup]. Example: Add-User-Devices [-From] <String> [-To] <String> [-E] [-M] [<CommonParameters>] Note: <string> is the ObjectID of the User and Device groups. .PARAMETER UserGroup Specifies the name of the user group where users can be found. .PARAMETER DeviceGroup Specifies the name of the device group where registered devices should be placed. .PARAMETER Excel Optional: Generates an excel spreadsheet report and will open in excel if installed. .PARAMETER Mobile Optional: Specifies the name of the device group where registered mobile devices should be placed. .EXAMPLE PS C:\> Add-User-Devices -UserGroup <ObjectID> -DeviceGroup <ObjectID> .EXAMPLE PS C:\> Add-User-Devices -From <ObjectID> -To <ObjectID> .EXAMPLE PS C:\> Add-User-Devices -From <ObjectID> -To <ObjectID> -Excel .EXAMPLE PS C:\> Add-User-Devices -From <ObjectID> -To <ObjectID> -Mobile .EXAMPLE PS C:\> Add-User-Devices -From <ObjectID> -To <ObjectID> -E -M .LINK https://www.powershellgallery.com/packages/UsersToDevices #> [CmdletBinding()] Param( [Parameter(Mandatory = $True,HelpMessage='User Group ObjectId')] [Alias("From")] [String] $UserGroup, [Parameter(Mandatory = $True,HelpMessage='Device Group ObjectId')] [Alias("To")] [String] $DeviceGroup, [Parameter(Mandatory = $False)] [Alias("M")] [switch] $Mobile, [Parameter(Mandatory = $False)] [Alias("E")] [switch] $Excel ) if (!(Connected)) {Azure-Ad-Auth} #Write-Host "`nFinding registered devices" $UserList = Get-AzureADGroupMember -ObjectId $UserGroup -All $true | Sort-Object -Property DisplayName If (!($UserList)) { Write-Host "No users were found - exiting" ; break } Write-Host ("`nProcessing details for {0} users" -f $UserList.count) -ForegroundColor Green $DeviceList = Get-AzureADGroupMember -ObjectId $DeviceGroup -All $true | Sort-Object -Property DisplayName $global:UserGroupName = (Get-AzureADGroup -objectid $UserGroup).displayname $global:DeviceGroupName = (Get-AzureADGroup -objectid $DeviceGroup).displayname $i = 0 foreach ($User in $UserList) { $i++ Write-Host ("`nFinding devices registered to {0} ({1}/{2})" -f $User.DisplayName, $i, $UserList.count) -ForegroundColor Yellow $DeviceQuery = Get-AzureADUserRegisteredDevice -objectid $User.objectid -All $true if ($Mobile) { $Devices = $DeviceQuery | where-object { ($_.displayname -like "*iphone*") -or ($_.displayname -like "*ipad*") } } else { $Devices = $DeviceQuery | where-object { ($_.displayname -notlike "*iphone*") -and ($_.displayname -notlike "*MacBook*") -and ($_.displayname -notlike "*ipad*") -and ($_.displayname -notlike "*vdi*") -and ($_.displayname -notlike "*yealink*") -and ($_.displayname -notlike "*android*") } } $j = 0 foreach ($Device in $Devices) { $j++ if ($Device -ne $null) { if ($DeviceList.objectid -notcontains $Device.objectid) { Write-Host ("`nProcessing ({0}/{1}) devices for {2}" -f $j, $Devices.count, $User.DisplayName) -ForegroundColor Green Write-Host ("`nAdding {0}'s {1} to {2}" -f $User.DisplayName, $Device.displayname, $DeviceGroupName) -ForegroundColor Cyan Add-AzureADGroupMember -ObjectId $DeviceGroup -RefObjectId $Device.objectid } else { Write-Host ("`nProcessing ({0}/{1}) devices for {2}" -f $j, $Devices.count, $User.DisplayName) -ForegroundColor Green Write-Host ("`n{0}'s {1} is already a member of {2}" -f $User.DisplayName, $Device.displayname, $DeviceGroupName) -ForegroundColor Red } } } } write-host "" Write-Host -ForegroundColor Yellow -NoNewLine 'Press any key to continue and generate report... '; $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); if ($Excel) { Get-Report -From $UserGroup -To $DeviceGroup -Excel } else { Get-Report -From $UserGroup -To $DeviceGroup } } function Connected() { $retval = $true try { $Status = Get-AzureADTenantDetail } catch [Microsoft.Open.Azure.AD.CommonLibrary.AadNeedAuthenticationException] { $retval = $false return $retval } return $retval } function Azure-Ad-Auth() { $NuGet = (Get-packageprovider -ListAvailable -Name NuGet -ea silentlycontinue) if (!$NuGet) { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force | Out-Null } Import-PackageProvider -Name NuGet | Out-Null $AzureAD = (Get-Module -ListAvailable -Name AzureAD -ea silentlycontinue) if (!$AzureAD) { Install-Module -Name AzureAD -Force | Out-Null } Import-Module AzureAD | Out-Null $mod = get-module AzureAD if ($mod -ne $null) { try { clear Connect-AzureAD clear } catch { clear write-host Write-warning "Could not connect to Azure AD" write-host exit } } } function Get-Report() { <# .SYNOPSIS Generates report based on registered devices of users in UserGroup and devices in DeviceGroup. .DESCRIPTION Author: David Velasquez Dependencies: AzureAD Module NuGet provider version '2.8.5.201' or newer Optional Dependency: ImportExcel Module Accepts [-Excel] as optional parameter to generate an excel spreadsheet report. Accepts [-E] as parameter alias for [-Excel]. Accepts [-From] and [-To] as parameter aliases for [-UserGroup] and [-DeviceGroup]. Example: Get-Report [-From] <String> [-To] <String> [-E] [<CommonParameters>] Note: <string> is the ObjectID of the User and Device groups. .PARAMETER UserGroup Specifies the name of the user group where users can be found. .PARAMETER DeviceGroup Specifies the name of the device group where registered devices should be located. .PARAMETER Excel Optional: Generates an excel spreadsheet report and will open in excel if installed. .EXAMPLE PS C:\> Get-Report -UserGroup <ObjectID> -DeviceGroup <ObjectID> .EXAMPLE PS C:\> Get-Report -From <ObjectID> -To <ObjectID> .EXAMPLE PS C:\> Get-Report -From <ObjectID> -To <ObjectID> -Excel .EXAMPLE PS C:\> Get-Report -From <ObjectID> -To <ObjectID> -E .LINK https://www.powershellgallery.com/packages/UsersToDevices #> [CmdletBinding()] Param( [Parameter(Mandatory = $True,HelpMessage='User Group ObjectId')] [Alias("From")] [String] $UserGroup, [Parameter(Mandatory = $True,HelpMessage='Device Group ObjectId')] [Alias("To")] [String] $DeviceGroup, [Parameter(Mandatory = $False)] [Alias("E")] [switch] $Excel ) if (!(Connected)) {Azure-Ad-Auth} $UserList = Get-AzureADGroupMember -ObjectId $UserGroup -All $true | Sort-Object -Property DisplayName $DeviceList = Get-AzureADGroupMember -ObjectId $DeviceGroup -All $true | Sort-Object -Property DisplayName $global:UserGroupName = (Get-AzureADGroup -objectid $UserGroup).displayname $global:DeviceGroupName = (Get-AzureADGroup -objectid $DeviceGroup).displayname $global:Report = [System.Collections.Generic.List[Object]]::new() foreach ($User in $UserList) { $DeviceQuery = Get-AzureADUserRegisteredDevice -objectid $User.objectid -All $true $Devices = $DeviceQuery | where-object { ($_.displayname -notlike "*iphone*") -and ($_.displayname -notlike "*ipad*") -and ($_.displayname -notlike "*MacBook*") -and ($_.displayname -notlike "*vdi*") -and ($_.displayname -notlike "*android*") -and ($_.displayname -notlike "*yealink*") } $iPhones = $DeviceQuery | where-object {$_.displayname -like "*iphone*"} $iPads = $DeviceQuery | where-object {$_.displayname -like "*ipad*"} $Laptops = $DeviceQuery | where-object {$_.displayname -like "*-LT-*"} $AppleLaptops = $DeviceQuery | where-object {$_.displayname -like "*MacBook*"} $Desktops = $DeviceQuery | where-object { ($_.displayname -notlike "*iphone*") -and ($_.displayname -notlike "*ipad*") -and ($_.displayname -notlike "*MacBook*") -and ($_.displayname -notlike "*vdi*") -and ($_.displayname -notlike "*-LT-*") -and ($_.displayname -notlike "*android*") -and ($_.displayname -notlike "*yealink*") } $MobileDevices = $DeviceQuery | where-object { ($_.displayname -like "*iphone*") -or ($_.displayname -like "*ipad*") } $VirtualDesktops = $DeviceQuery | where-object {$_.displayname -like "*VDI-*"} $DevicesInDeviceGroup = $DeviceQuery | where-object { ($_.objectid -in $DeviceList.objectid) -and ($_.displayname -notlike "*iphone*") -and ($_.displayname -notlike "*ipad*") -and ($_.displayname -notlike "*MacBook*") -and ($_.displayname -notlike "*vdi*") -and ($_.displayname -notlike "*android*") } $MobileDevicesInDeviceGroup = $DeviceQuery | where-object { ($_.objectid -in $DeviceList.objectid) -and ($_.displayname -like "*iphone*") -or ($_.displayname -like "*ipad*") } $Lines = [PSCustomObject]@{ User = $User.displayname UserObjectID = $User.objectid UserGroup = $UserGroupName UserGroupObjectID = $UserGroup DeviceGroup = $DeviceGroupName DeviceGroupObjectID = $DeviceGroup Devices = $Devices.displayname DeviceObjectIDs = $Devices.objectid DesktopDevices = $Desktops.displayname DesktopDeviceIDs = $Desktops.objectid LaptopDevices = $Laptops.displayname LaptopDeviceIDs = $Laptops.objectid AppleLaptopDevices = $AppleLaptops.displayname AppleLaptopDeviceIDs = $AppleLaptops.objectid iPadDevices = $iPads.displayname iPadDeviceIDs = $iPads.objectid iPhoneDevices = $iPhones.displayname iPhoneDeviceIDs = $iPhones.objectid VirtualDesktopDevices = $VirtualDesktops.displayname VirtualDesktopDeviceIDs = $VirtualDesktops.objectid CustomAttributes = $null DevicesInDeviceGroup = $DevicesInDeviceGroup.displayname DevicesInDeviceGroupIDs = $DevicesInDeviceGroup.objectid MobileDevicesInDeviceGroup = $MobileDevicesInDeviceGroup.displayname MobileDevicesInDeviceGroupIDs = $MobileDevicesInDeviceGroup.objectid } $Report.Add($Lines) } clear Write-Host "`nGenerated Report" Write-Host "----------------`n" $Report $Report | Pretty-Table | Out-GridView -Title "Generated Report" $ExcelParam = $null if ($Excel) { if ((Enum-Excel-Module)) { $ExcelParam = "-Excel" Output-To-Excel } } write-host "`nReport Generated by running:" -ForegroundColor Magenta write-host ("Get-Report -From {0} -To {1} {2}" -f $UserGroup, $DeviceGroup, $ExcelParam) -ForegroundColor Magenta } function Output-To-Excel() { $xlfile = "$env:USERPROFILE\Desktop\PSreport.xlsx" Remove-Item $xlfile -ErrorAction SilentlyContinue $excel = $Report | Pretty-Table | Export-Excel $xlfile -AutoSize -StartRow 2 -TableName GeneratedReport -PassThru $ws = $excel.Workbook.Worksheets['Sheet1'] $xlParams = @{WorkSheet=$ws;Bold=$true;FontSize=24;AutoSize=$true} Set-Format -Range A1 -Value "Generated Report" @xlParams $ws.Cells["A1:B1"].merge = $true $ws.Cells["A:B"].Style.HorizontalAlignment="Center" Set-ExcelRange -Worksheet $ws -Range "A:B" -Width 50 #Set-ExcelRange -Worksheet $ws -Range "A3:B3" -Bold $rowMax = ($ws).dimension.rows $colNameA = "A" $columnB = "B" for ($i=3; $i -le $rowMax-1; $i = $i + 25) { $range = -join($colNameA, $i, ":", $columnB, $i) Set-ExcelRange -Worksheet $ws -Range "$range" -Bold -FontSize "20" } write-host ("Generated Report Saved to: {0}" -f $xlfile) -ForegroundColor Magenta $HasOffice = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\O365ProPlusRetail*).displayname if ($HasOffice) { Close-ExcelPackage $excel -show } else { Close-ExcelPackage $excel } } function Pretty-Table() { param ( [Object] [Parameter(Mandatory=$true, ValueFromPipeline=$true)] $InputObject ) process { $InputObject | ForEach-Object { foreach ($Property in $_.psobject.properties) { $Hash = [ordered]@{ Property=$Property.name Value=$Property.value } [PSCustomObject]$Hash } } } } function Enum-Excel-Module() { Import-PackageProvider -Name NuGet | Out-Null $ImportExcel = (Get-Module -ListAvailable -Name ImportExcel -ea silentlycontinue) if (!$ImportExcel) { Set-PSRepository -Name PSGallery -InstallationPolicy Trusted | Out-Null Install-Module -Name ImportExcel -Force | Out-Null } Import-Module ImportExcel | Out-Null $mod = get-module ImportExcel if ($mod -ne $null) { return $true } } Export-ModuleMember -function * -alias * |