Skip to content

Commit 2ba3a98

Browse files
authored
Merge pull request #796 from LeonArmston/LeonArmston-SPAgents-Config-Creation
New Sample: Dynamically Create .agent file for SharePoint Agents
2 parents 604f8ae + eb7f08b commit 2ba3a98

File tree

4 files changed

+309
-0
lines changed

4 files changed

+309
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
---
2+
plugin: add-to-gallery
3+
---
4+
5+
# Creating SharePoint Agents (.agent Files) with PowerShell
6+
7+
## Summary
8+
9+
I have written a script to automate the creation of .agent files which you can then add to your sites & libraries. In the script you can then specify the details for the copilot i.e. name, welcome message, starter prompts & sources for the agent i.e. specific files, folders, libraries or sites that the agent is then grounded on. The script uses search to find the site ids, web ids and unique Ids of documents.
10+
11+
![Example Screenshot](assets/preview.png)
12+
13+
14+
**Minimum Steps To Success**
15+
16+
* Enter a URL of a SharePoint site you have access to.
17+
* Run the script (you will be asked for the following:)
18+
* Name of the SharePoint Agent
19+
* Description of the Agent
20+
* Custom welcome message for the Agent
21+
* Instructions for the Agent
22+
* Enter at least one Starter Prompt i.e "How can you help me?"
23+
* Enter at least one SharePoint source (File, Folder, Library or Site)
24+
* Add created <Agent Name>.agent file to /SiteAssets/Copilots folder.
25+
26+
Further details on my [blog article](https://www.leonarmston.com/2025/01/creating-sharepoint-agents-with-powershell/) (External Site)
27+
28+
### Prerequisites
29+
30+
Account that runs the script needs access to all of the locations where the files, folders, libraries or sites to be used in the agent are located.
31+
32+
# [PnP PowerShell](#tab/pnpps)
33+
34+
```powershell
35+
$url = "https://contoso.sharepoint.com/sites/Syntex"
36+
37+
38+
Connect-PnPOnline -Url $url -Interactive
39+
40+
# Function to prompt user for conversation starters
41+
function Get-ConversationStarters {
42+
$conversationStarters = @()
43+
while ($true) {
44+
$text = Read-Host "Enter a starter prompt (or press Enter to finish)"
45+
if ($text -eq "" -and $conversationStarters.Count -eq 0) {
46+
Write-Host "You must enter at least one starter prompt."
47+
} elseif ($text -eq "") {
48+
break
49+
} else {
50+
$conversationStarters += @{ text = $text }
51+
}
52+
}
53+
return $conversationStarters
54+
}
55+
56+
# Function to prompt user for capabilities
57+
function Get-Capabilities {
58+
$items_by_sharepoint_ids = @()
59+
$items_by_url = @()
60+
while ($true) {
61+
$type = Read-Host "Enter capability type (File, Site, Library, Folder) (or press Enter to finish)"
62+
$path = Read-Host "Enter path (or press Enter to finish)"
63+
if ($type -eq "" -or $path -eq "") { break }
64+
65+
switch ($type) {
66+
"File" {
67+
68+
<#{
69+
"list_id": "50f033bf-f372-48ac-8bd6-6af3f421a1c6",
70+
"name": "PnP Recognition Letter - Leon.pdf",
71+
"site_id": "18dfc66a-2fa5-4b83-adf5-8726b62a6861",
72+
"type": "File",
73+
"unique_id": "9328a5ca-dd8e-4e46-a51e-782e53d7275d",
74+
"url": "https://leonarmstonmvp.sharepoint.com/sites/Syntex/Shared%20Documents/PnP%20Recognition%20Letter%20-%20Leon.pdf",
75+
"web_id": "b0224f93-49be-4957-8e22-edbb489c937e"
76+
}#>
77+
78+
$searchQuery = Submit-PnPSearchQuery -Query "Path:`"$path`"" -All -SelectProperties "ListId","FileType","SiteTitle","IdentityListItemId","Path","IdentityWebId"
79+
80+
81+
$capability = @{
82+
list_id = $searchQuery.ResultRows[0].ListId
83+
name = $searchQuery.ResultRows[0].OriginalPath.Split("/")[-1]
84+
site_id = $searchQuery.ResultRows[0].IdentitySiteCollectionId
85+
type = $type
86+
unique_id = $searchQuery.ResultRows[0].IdentityListItemId
87+
url = $searchQuery.ResultRows[0].Path
88+
web_id = $searchQuery.ResultRows[0].IdentityWebId
89+
}
90+
$items_by_sharepoint_ids += $capability
91+
}
92+
"Site" {
93+
<#{
94+
"list_id": "00000000-0000-0000-0000-000000000000",
95+
"name": "Projects Hub",
96+
"site_id": "171f7026-6c47-45ce-a734-21f0ee741965",
97+
"type": "Site",
98+
"unique_id": "00000000-0000-0000-0000-000000000000",
99+
"url": "https://leonarmstonmvp.sharepoint.com/sites/ProjectsHub",
100+
"web_id": "b0224f93-49be-4957-8e22-edbb489c937e"
101+
}#>
102+
103+
$searchQuery = Submit-PnPSearchQuery -Query "Path:`"$path`" contentclass:`"STS_Site`"" -All -SelectProperties "ListId","FileType","SiteTitle","IdentityListItemId","Path","IdentityWebId","IdentitySiteId"
104+
105+
$capability = @{
106+
list_id = "00000000-0000-0000-0000-000000000000"
107+
name = $searchQuery.ResultRows[0].SiteTitle
108+
site_id = $searchQuery.ResultRows[0].IdentitySiteCollectionId
109+
type = $type
110+
unique_id = "00000000-0000-0000-0000-000000000000"
111+
url = $searchQuery.ResultRows[0].SPWebUrl
112+
web_id = $searchQuery.ResultRows[0].IdentityWebId
113+
}
114+
$items_by_url += $capability
115+
}
116+
"Folder" {
117+
<#
118+
{
119+
"list_id": "a1ed0c2f-aa4c-4a4f-a3ce-23c745fe17d0",
120+
"name": "NORR",
121+
"site_id": "18dfc66a-2fa5-4b83-adf5-8726b62a6861",
122+
"type": "Folder",
123+
"unique_id": "057676b7-9212-44cb-8321-d5df359be4d7",
124+
"url": "https://leonarmstonmvp.sharepoint.com/sites/Syntex/DrawingPlansDiffCompanies/NORR",
125+
"web_id": "b0224f93-49be-4957-8e22-edbb489c937e"
126+
}
127+
#>
128+
$searchQuery = Submit-PnPSearchQuery -Query "Path:`"$path`" IsContainer:true" -All -SelectProperties "ListId","FileType","SiteTitle","IdentityListItemId","Path","IdentityWebId","IdentitySiteId"
129+
130+
$capability = @{
131+
list_id = $searchQuery.ResultRows[0].ListId
132+
name = $searchQuery.ResultRows[0].Title
133+
site_id = $searchQuery.ResultRows[0].SiteId
134+
type = $type
135+
unique_id = $searchQuery.ResultRows[0].UniqueId -replace "{","" -replace "}","".Trim()
136+
url = $searchQuery.ResultRows[0].OriginalPath
137+
web_id = $searchQuery.ResultRows[0].WebId
138+
}
139+
$items_by_url += $capability
140+
}
141+
"Library" {
142+
<# {
143+
"list_id": "e042afcd-15d9-4790-a125-264e3b80cdaf",
144+
"name": "Autofill",
145+
"site_id": "18dfc66a-2fa5-4b83-adf5-8726b62a6861",
146+
"type": "Folder",
147+
"unique_id": "00000000-0000-0000-0000-000000000000",
148+
"url": "https://leonarmstonmvp.sharepoint.com/sites/Syntex/Autofill",
149+
"web_id": "b0224f93-49be-4957-8e22-edbb489c937e"
150+
}
151+
#>
152+
$searchQuery = Submit-PnPSearchQuery -Query "Path:`"$path`" contentclass:`"STS_List_DocumentLibrary`"" -All -SelectProperties "ListId","FileType","SiteTitle","IdentityListItemId","Path","IdentityWebId","IdentitySiteId"
153+
154+
$capability = @{
155+
list_id = $searchQuery.ResultRows[0].ListId
156+
name = $searchQuery.ResultRows[0].Title
157+
site_id = $searchQuery.ResultRows[0].SiteId
158+
type = "Folder"
159+
unique_id = "00000000-0000-0000-0000-000000000000"
160+
url = $searchQuery.ResultRows[0].OriginalPath.Split("/Forms")[0]
161+
web_id = $searchQuery.ResultRows[0].WebId
162+
}
163+
$items_by_url += $capability
164+
}
165+
default {
166+
Write-Host "Invalid type entered. Please enter either File, Site, or Folder."
167+
}
168+
}
169+
}
170+
return @{ items_by_sharepoint_ids = $items_by_sharepoint_ids; items_by_url = $items_by_url }
171+
}
172+
173+
# Prompt user for name
174+
$name = Read-Host "Enter a custom name for the SharePoint Agent (or press Enter to use the default `"Leon's Agent`")"
175+
if($name -eq "")
176+
{
177+
$name = "Leon's Agent"
178+
}
179+
Write-Host " Name: $name"
180+
181+
182+
$description = Read-Host "Enter a custom description for the SharePoint Agent (or press Enter to use the default 'This is an agent curated based on the content from the selected file sources.')"
183+
if($description -eq "")
184+
{
185+
$description = "This is an agent curated based on the content from the selected file sources."
186+
}
187+
Write-Host " Description: $description"
188+
189+
$welcomeMessageText = Read-Host "Enter a custom welcome message for the SharePoint Agent (or press Enter to use the default 'Welcome! Enhance your productivity with this Copilot agent. Start a conversation by asking a question or selecting one of the suggested prompts.')"
190+
if($welcomeMessageText -eq "")
191+
{
192+
$welcomeMessageText = "Welcome! Enhance your productivity with this Copilot agent. Start a conversation by asking a question or selecting one of the suggested prompts."
193+
}
194+
Write-Host " Welcome Message: $welcomeMessageText"
195+
196+
$instructions = Read-Host "Enter custom instructions for the agent (or press Enter to use the default 'Provide helpful, accurate, and relevant information while maintaining a professional and courteous tone.')"
197+
if($instructions -eq "")
198+
{
199+
$instructions = "Provide helpful, accurate, and relevant information while maintaining a professional and courteous tone."
200+
}
201+
Write-Host " Instructions: $instructions"
202+
203+
# Get user input
204+
$conversationStarters = Get-ConversationStarters
205+
$capabilities = Get-Capabilities
206+
207+
# Create JSON structure
208+
$json = @{
209+
customCopilotConfig = @{
210+
conversationStarters = @{
211+
conversationStarterList = @($conversationStarters)
212+
welcomeMessage = @{
213+
text = $welcomeMessageText
214+
}
215+
}
216+
gptDefinition = @{
217+
capabilities = @(
218+
@{
219+
items_by_sharepoint_ids = $capabilities.items_by_sharepoint_ids
220+
items_by_url = $capabilities.items_by_url
221+
name = "OneDriveAndSharePoint"
222+
}
223+
)
224+
description = $description
225+
instructions = $instructions
226+
name = $name
227+
}
228+
icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
229+
}
230+
schemaVersion = "0.2.0"
231+
}
232+
233+
# Convert to JSON and save to file
234+
$json | ConvertTo-Json -Depth 10 | Out-File "$($name).agent"
235+
236+
Write-Host "JSON file generated: $($name).agent"
237+
238+
```
239+
[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)]
240+
***
241+
242+
243+
## Contributors
244+
245+
| Author(s) |
246+
|-----------|
247+
| Leon Armston |
248+
249+
[!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)]
250+
<img src="https://m365-visitor-stats.azurewebsites.net/script-samples/scripts/spo-dev-agent-config-creation" aria-hidden="true" />
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
[
2+
{
3+
"name": "spo-dev-agent-config-creation",
4+
"source": "pnp",
5+
"title": "Creating SharePoint Agents (.agent Files) with PowerShell",
6+
"shortDescription": "Dyanmic creation of SharePoint Agents (.agent files) using PowerShell. Specify instructions, sample prompts and ground on files, folder, libraries or sites.",
7+
"url": "https://pnp.github.io/script-samples/spo-dev-agent-config-creation/README.html",
8+
"longDescription": [
9+
"This script sample demonstrates how to create SharePoint Agents (.agent files) using PnP PowerShell. The script allows you to specifyfor the Agent instructions, sample prompts, and ground on files, folders, libraries, or sites. All of the JSON is then created and then a .copilot file is created with all the configuration of the Agent ready to be deployed on your sites. Alternatively use the pattern and deploy your own customised SharePoint agents as part of your provisioning solution."
10+
],
11+
"creationDateTime": "2025-01-10",
12+
"updateDateTime": "2025-01-10",
13+
"products": [
14+
"SharePoint",
15+
"Microsoft 365 Copilot"
16+
],
17+
"metadata": [
18+
{
19+
"key": "PNP-POWERSHELL",
20+
"value": "2.99.90"
21+
}
22+
],
23+
"categories": [
24+
"Deploy",
25+
"Provision",
26+
"Configure",
27+
"AI",
28+
"Microsoft 365 Copilot"
29+
],
30+
"tags": [
31+
"Connect-PnPOnline",
32+
"Submit-PnPSearchQuery",
33+
"ConvertTo-Json"
34+
],
35+
"thumbnails": [
36+
{
37+
"type": "image",
38+
"order": 100,
39+
"url": "https://raw.githubusercontent.com/pnp/script-samples/main/scripts/spo-dev-agent-config-creation/assets/preview.png",
40+
"alt": "Preview of the sample Creating SharePoint Agents (.agent Files) with PowerShell"
41+
}
42+
],
43+
"authors": [
44+
{
45+
"gitHubAccount": "Leon Armston",
46+
"company": "",
47+
"pictureUrl": "https://avatars.githubusercontent.com/u/12968962?v=4",
48+
"name": "Leon Armston"
49+
}
50+
],
51+
"references": [
52+
{
53+
"name": "Want to learn more about PnP PowerShell and the cmdlets",
54+
"description": "Check out the PnP PowerShell site to get started and for the reference to the cmdlets.",
55+
"url": "https://aka.ms/pnp/powershell"
56+
}
57+
]
58+
}
59+
]

0 commit comments

Comments
 (0)