Skip to content

Commit a3c7b6d

Browse files
committed
"Initial commit"
0 parents  commit a3c7b6d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+5561
-0
lines changed

.gitattributes

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Needed for publishing of examples, build worker defaults to core.autocrlf=input.
2+
* text eol=autocrlf
3+
4+
*.mof text eol=crlf
5+
*.sh text eol=lf
6+
*.svg eol=lf
7+
8+
# Ensure any exe files are treated as binary
9+
*.exe binary
10+
*.jpg binary
11+
*.xl* binary
12+
*.pfx binary
13+
*.png binary
14+
*.dll binary
15+
*.so binary

.gitignore

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
output/
2+
3+
**.bak
4+
*.local.*
5+
!**/README.md
6+
.kitchen/
7+
8+
*.nupkg
9+
*.suo
10+
*.user
11+
*.coverage
12+
.vs
13+
.psproj
14+
.sln
15+
markdownissues.txt
16+
node_modules
17+
package-lock.json
18+
ZZBuild-Help.ps1

.vscode/tasks.json

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
{
2+
"version": "2.0.0",
3+
"_runner": "terminal",
4+
"windows": {
5+
"options": {
6+
"shell": {
7+
"executable": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
8+
"args": [
9+
"-NoProfile",
10+
"-ExecutionPolicy",
11+
"Bypass",
12+
"-Command"
13+
]
14+
}
15+
}
16+
},
17+
"linux": {
18+
"options": {
19+
"shell": {
20+
"executable": "/usr/bin/pwsh",
21+
"args": [
22+
"-NoProfile",
23+
"-Command"
24+
]
25+
}
26+
}
27+
},
28+
"osx": {
29+
"options": {
30+
"shell": {
31+
"executable": "/usr/local/bin/pwsh",
32+
"args": [
33+
"-NoProfile",
34+
"-Command"
35+
]
36+
}
37+
}
38+
},
39+
"tasks": [
40+
{
41+
"label": "build",
42+
"type": "shell",
43+
"command": "&${cwd}/build.ps1",
44+
"args": [],
45+
"presentation": {
46+
"echo": true,
47+
"reveal": "always",
48+
"focus": true,
49+
"panel": "new",
50+
"clear": false
51+
},
52+
"runOptions": {
53+
"runOn": "default"
54+
},
55+
"problemMatcher": [
56+
{
57+
"owner": "powershell",
58+
"fileLocation": [
59+
"absolute"
60+
],
61+
"severity": "error",
62+
"pattern": [
63+
{
64+
"regexp": "^\\s*(\\[-\\]\\s*.*?)(\\d+)ms\\s*$",
65+
"message": 1
66+
},
67+
{
68+
"regexp": "(.*)",
69+
"code": 1
70+
},
71+
{
72+
"regexp": ""
73+
},
74+
{
75+
"regexp": "^.*,\\s*(.*):\\s*line\\s*(\\d+).*",
76+
"file": 1,
77+
"line": 2
78+
}
79+
]
80+
}
81+
]
82+
},
83+
{
84+
"label": "test",
85+
"type": "shell",
86+
"command": "&${cwd}/build.ps1",
87+
"args": ["-AutoRestore","-Tasks","test"],
88+
"presentation": {
89+
"echo": true,
90+
"reveal": "always",
91+
"focus": true,
92+
"panel": "dedicated",
93+
"showReuseMessage": true,
94+
"clear": false
95+
},
96+
"problemMatcher": [
97+
{
98+
"owner": "powershell",
99+
"fileLocation": [
100+
"absolute"
101+
],
102+
"severity": "error",
103+
"pattern": [
104+
{
105+
"regexp": "^\\s*(\\[-\\]\\s*.*?)(\\d+)ms\\s*$",
106+
"message": 1
107+
},
108+
{
109+
"regexp": "(.*)",
110+
"code": 1
111+
},
112+
{
113+
"regexp": ""
114+
},
115+
{
116+
"regexp": "^.*,\\s*(.*):\\s*line\\s*(\\d+).*",
117+
"file": 1,
118+
"line": 2
119+
}
120+
]
121+
}
122+
]
123+
}
124+
]
125+
}

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Changelog for GraphAppToolkit
2+
3+
The format is based on and uses the types of changes according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5+
6+
## [Unreleased]
7+
8+
### Added
9+
10+
- Initial release of GraphAppToolkit

GitVersion.yml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
mode: ContinuousDelivery
2+
next-version: 0.0.1
3+
major-version-bump-message: '(breaking\schange|breaking|major)\b'
4+
minor-version-bump-message: '(adds?|features?|minor)\b'
5+
patch-version-bump-message: '\s?(fix|patch)'
6+
no-bump-message: '\+semver:\s?(none|skip)'
7+
assembly-informational-format: '{NuGetVersionV2}+Sha.{Sha}.Date.{CommitDate}'
8+
branches:
9+
master:
10+
tag: preview
11+
regex: ^main$
12+
pull-request:
13+
tag: PR
14+
feature:
15+
tag: useBranchName
16+
increment: Minor
17+
regex: f(eature(s)?)?[\/-]
18+
source-branches: ['master']
19+
hotfix:
20+
tag: fix
21+
increment: Patch
22+
regex: (hot)?fix(es)?[\/-]
23+
source-branches: ['master']
24+
25+
ignore:
26+
sha: []
27+
merge-message-formats: {}
28+
29+
30+
# feature:
31+
# tag: useBranchName
32+
# increment: Minor
33+
# regex: f(eature(s)?)?[/-]
34+
# source-branches: ['master']
35+
# hotfix:
36+
# tag: fix
37+
# increment: Patch
38+
# regex: (hot)?fix(es)?[/-]
39+
# source-branches: ['master']
40+

README.md

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# GraphAppToolkit Module
2+
3+
## Summary
4+
5+
The **GraphAppToolkit** module provides a set of functions and classes to quickly create, configure, and manage Azure AD (Entra) application registrations for various Microsoft 365 scenarios. It focuses on app-only authentication with certificates, storing credentials securely in SecretManagement vaults, and simplifying tasks like sending emails from a service principal, managing mail-enabled groups, and publishing specialized apps for M365 auditing or MEM policy management.
6+
7+
## Help Documentation
8+
9+
In addition to in-line PowerShell help (`Get-Help <FunctionName> -Full`), you can refer to the `about_GraphAppToolkit.help.txt` file (if included in the module) or any published documentation for more details on usage.
10+
11+
## Public Functions
12+
13+
The following Public Functions are exposed by the **GraphAppToolkit** module:
14+
15+
- **New-MailEnabledSendingGroup**
16+
Creates a new mail-enabled security group in Exchange Online for restricted send scenarios.
17+
18+
- **Publish-TkEmailApp**
19+
Publishes a Microsoft Graph Email App with certificate-based authentication and optionally restricts sending to a specific mail-enabled group.
20+
21+
- **Publish-TkM365AuditApp**
22+
Publishes an Azure AD application with read-only or read-write sets of Graph/SharePoint/Exchange permissions for auditing or compliance tasks.
23+
24+
- **Publish-TkMemPolicyManagerApp**
25+
Publishes an Azure AD application for MEM (Intune) policy management, supporting read-only or read-write permissions.
26+
27+
- **Send-TkEmailAppMessage**
28+
Sends an email using a previously published email app’s certificate-based authentication (no user mailbox required).
29+
30+
## Private Functions
31+
32+
The following Private Functions support the module’s internal processes and are not exported:
33+
34+
- **Connect-TkMsService**
35+
- **ConvertTo-ParameterSplat**
36+
- **Initialize-TkAppAuthCertificate**
37+
- **Initialize-TkAppSpRegistration**
38+
- **Initialize-TkModuleEnv**
39+
- **New-TkAppName**
40+
- **New-TkAppRegistration**
41+
- **New-TkExchangeEmailAppPolicy**
42+
- **New-TkRequiredResourcePermissionObject**
43+
- **Set-TkJsonSecret**
44+
- **Test-IsAdmin**
45+
- **Write-AuditLog**
46+
47+
These private functions handle core logic like certificate generation, connecting to Microsoft services, app registration, secret storage, and logging.
48+
49+
---
50+
51+
## Examples
52+
53+
### Example 1: Creating a Mail-Enabled Security Group
54+
55+
```powershell
56+
$DefaultDomain = 'contoso.com'
57+
$MailEnabledSendingGroupToCreate = "CTSO-GraphAPIMail"
58+
# Creates a mail-enabled security group named "MySenders" using a default domain
59+
$group = New-MailEnabledSendingGroup -Name $MailEnabledSendingGroupToCreate -DefaultDomain $DefaultDomain
60+
```
61+
62+
### Example 2: Publishing a Graph Email App
63+
64+
# Publishes an email app restricted to a mail-enabled group
65+
66+
```powershell
67+
# Uses Group Variable from Example 1
68+
$LicensedUserToSendAs = '[email protected]'
69+
$TwoToFourLetterCompanyAbbreviation = "CTSO"
70+
Publish-TkEmailApp `
71+
-AppPrefix $TwoToFourLetterCompanyAbbreviation `
72+
-AuthorizedSenderUserName $LicensedUserToSendAs `
73+
-MailEnabledSendingGroup $group.PrimarySmtpAddress `
74+
-ReturnParamSplat
75+
```
76+
77+
### Example 3: Sending Email from the Published App
78+
79+
```powershell
80+
# Param Splat returned from Example 2 will have all values populated
81+
$params = @{
82+
AppId = "your-app-id"
83+
Id = "your-app-object-id"
84+
AppName = "CN=YourAppName"
85+
AppRestrictedSendGroup = "[email protected]"
86+
CertExpires = "yyyy-MM-dd HH:mm:ss"
87+
CertThumbprint = "your-cert-thumbprint"
88+
ConsentUrl = "https://login.microsoftonline.com/your-tenant-id/adminconsent?client_id=your-app-id"
89+
DefaultDomain = 'contoso.com'
90+
SendAsUser = 'helpdesk'
91+
SendAsUserEmail = '[email protected]'
92+
TenantID = "your-tenant-id"
93+
}
94+
# Sends an email using a previously published TkEmailApp
95+
Send-TkEmailAppMessage `
96+
-AppName $params.AppName `
97+
98+
-FromAddress $params.SendAsUserEmail `
99+
-Subject 'Test Email' `
100+
-EmailBody 'This is a test email.' `
101+
-AttachmentPath 'C:\temp\attachmentFile.zip', 'C:\temp\anotherAttachmentFile.zip' `
102+
-ReturnParamSplat
103+
104+
# Send using manual parameters
105+
$AppId = "00000000-1111-2222-3333-444444444444"
106+
$TenantId = "00000000-1111-2222-3333-444444444444"
107+
$CertThumbprint = "AABBCCDDEEFF11223344556677889900"
108+
109+
$FromAddress = '[email protected]'
110+
Send-TkEmailAppMessage `
111+
-AppId $AppId `
112+
-TenantId $TenantId `
113+
-CertThumbprint $CertThumbprint `
114+
-To $To `
115+
-FromAddress $FromAddress `
116+
-Subject "Manual Email" `
117+
-EmailBody "Hello from Manual!"
118+
```
119+
120+
### Example 4: Publishing an M365 Audit App
121+
122+
```powershell
123+
# Publishes a read-only M365 audit app (e.g., for directory or device management auditing)
124+
Publish-TkM365AuditApp -AppPrefix "CSN" -CertThumbprint "FACEBEEFBEEFAABBCCDDEEFF11223344"
125+
```
126+
127+
### Example 5: Publishing a MEM Policy Manager App
128+
129+
```powershell
130+
# Publishes a read-write MEM Policy Manager app with a self-signed cert
131+
Publish-TkMemPolicyManagerApp -AppPrefix "MEM" -ReadWrite
132+
```

RequiredModules.psd1

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@{
2+
PSDependOptions = @{
3+
AddToPath = $true
4+
Target = 'output\RequiredModules'
5+
Parameters = @{
6+
Repository = 'PSGallery'
7+
}
8+
}
9+
10+
InvokeBuild = 'latest'
11+
PSScriptAnalyzer = 'latest'
12+
Pester = 'latest'
13+
ModuleBuilder = 'latest'
14+
ChangelogManagement = 'latest'
15+
Sampler = 'latest'
16+
'Sampler.GitHubTasks' = 'latest'
17+
18+
19+
}
20+

0 commit comments

Comments
 (0)