แชร์ผ่าน


ตั้งค่าตัวแทนค่าใช้จ่าย (ตัวอย่าง)

สําคัญ

นำไปใช้กับ Dynamics 365 Project Operations ที่รวมกับ ERP และ Dynamics 365 Project Operations สำหรับการผลิต

เอเจนต์ค่าใช้จ่ายรวบรวมความสามารถต่างๆ จาก Microsoft Dynamics 365 Project Operations, แอปการเงินและการดำเนินงาน, Microsoft Copilot Studio, Power Automate และ Dataverse เพื่อดําเนินการเวิร์กโฟลว์การประมวลผลค่าใช้จ่ายโดยอัตโนมัติโดยใช้ AI คุณลักษณะนี้จะช่วยประหยัดเวลาและลดความพยายามด้วยตนเองโดยการเปิดใช้งานระบบของคุณเพื่อประมวลผลใบเสร็จรับเงินและสร้างรายงานค่าใช้จ่ายและรายงานค่าใช้จ่ายสําหรับผู้ใช้ ซึ่งใช้ตัวเชื่อมต่อ Microsoft Power Platform สําหรับการรวมกับ Outlook, Microsoft Teams, ปฏิทินของผู้ใช้ และสภาพแวดล้อมแอปการเงินและการดำเนินงานผ่านเอนทิตีเสมือน Dataverse

เอเจนต์ค่าใช้จ่ายประกอบด้วยโฟลว์หลายโฟลว์ ซึ่งมีสามรายการทําหน้าที่เป็นตัวควบคุมการทำงานร่วมกันหลัก:

  • ประมวลผลอีเมล – โฟลว์นี้จะสแกนโฟลเดอร์กล่องจดหมายที่กําหนดค่าไว้ทุกชั่วโมงและจัดเก็บสิ่งที่แนบมาเป็นใบเสร็จที่ไม่ได้แนบใน Dynamics 365 Finance
  • แยก ID ใบเสร็จ – โฟลว์นี้จะรับใบเสร็จที่ไม่ได้แนบและทริกเกอร์เอเจนต์เพื่อแยกรายละเอียดใบเสร็จและสร้างรายการค่าใช้จ่ายที่ไม่ได้แนบ
  • ประมวลผลรายงานค่าใช้จ่าย – โฟลว์นี้จะแปลงรายการค่าใช้จ่ายที่ไม่ได้จัดและสร้างรายงานค่าใช้จ่าย โดยยึดตาม รายงานกลุ่มตาม การกําหนดค่าที่คุณตั้งค่าในแอพลิเคชันสําหรับแต่ละเอนทิตีทางกฎหมาย

นอกจากนี้ เอเจนต์ยังรวมกับ Microsoft Teams เพื่อให้สามารถใช้การ์ดที่ปรับเปลี่ยนได้เพื่อการตรวจสอบและการส่งรายงานค่าใช้จ่าย

เอเจนต์อาศัยตัวเชื่อมต่อ Microsoft Power Platform หลายรายการ ตัวเชื่อมต่อเหล่านี้จะได้รับการอ้างอิงโดยอัตโนมัติในโฟลว์ Power Automate ที่มีให้

  • Outlook (Office 365) – ตัวเชื่อมต่อนี้เข้าถึงกล่องจดหมายที่ใช้ร่วมกันเพื่อแยกใบเสร็จ
  • Dataverse (เอนทิตีเสมือน) – ตัวเชื่อมต่อนี้รวมกับแอปการเงินและการดำเนินงานผ่านเอนทิตีเสมือน
  • Microsoft Copilot Studio – ตัวเชื่อมต่อนี้จะเรียกใช้โมเดล AI เพื่อแยกข้อมูลใบเสร็จ
  • Microsoft Teams – ตัวเชื่อมต่อนี้ส่งการ์ดที่ปรับเปลี่ยนได้สําหรับการโต้ตอบกับผู้ใช้ (หากเปิดใช้งานการรวม Teams)
  • ผู้ใช้ Microsoft 365 – ตัวเชื่อมต่อนี้ดึงรายละเอียดปฏิทินของผู้ใช้ (ไม่บังคับ หากการแยกวิเคราะห์ใบเสร็จเป็นไปตามบริบท)

ข้อกําหนดเบื้องต้น

  1. สภาพแวดล้อมด้านการเงินและการดําเนินงาน: คุณจําเป็นต้องมีเวอร์ชัน 10.0.44 (10.0.2263.167 และใหม่กว่า) หรือ 10.0.45 (10.0.2345.102 และใหม่กว่า) ของสภาพแวดล้อมการเงินและการดําเนินงานเพื่อติดตั้งตัวแทน
  2. บทบาทที่จําเป็นในการตั้งค่าผู้ใช้ของบริษัทตัวแทนค่าใช้จ่าย: เพื่อทําตามขั้นตอนในบทความนี้ คุณต้องเป็นผู้ดูแลระบบขององค์กร และมีบทบาทต่อไปนี้เพื่อตั้งค่าผู้ใช้ของบริษัทตัวแทนค่าใช้จ่ายสําหรับการติดตั้งตัวแทนค่าใช้จ่าย
ระบบ บทบาท ความคิดเห็น
ศูนย์จัดการ Power Platform ผู้ดูแลระบบ
  1. ไปที่ ศูนย์การจัดการ Power Platform
  2. ไปที่ จัดการ บนบานหน้าต่างด้านซ้าย เลือก สภาพแวดล้อม และจากนั้นเลือกสภาพแวดล้อมของคุณ
  3. ในส่วน การเข้าถึง>ผู้ใช้ เลือก ดูทั้งหมด
  4. เลือกผู้ใช้ แล้วเลือก จัดการบทบาท และเพิ่มบทบาท
Finance and Operations ผู้ดูแลระบบ
  1. เปิด URL แอปการเงินและการดำเนินงานสําหรับสภาพแวดล้อมของคุณ
  2. ไปที่ โมดูล>ระบบการดูแล>ผู้ใช้ และเลือกผู้ใช้
  3. เลือก เพิ่มบทบาท – ผู้ดูแลระบบ
Microsoft 365 ผู้ดูแลระบบ Exchange และผู้ดูแลระบบผู้ใช้
  1. ไปที่ ศูนย์การจัดการ Microsoft 365
  2. ไปที่ ผู้ใช้>ผู้ใช้ที่ใช้งานอยู่> เลือกผู้ใช้
  3. เลือก จัดการบทบาท จากนั้นจาก บทบาท เลือก ผู้ดูแลระบบ Exchange
  4. บันทึกการเปลี่ยนแปลง
  5. ทําตามขั้นตอนเดียวกันเพื่อเพิ่มบทบาท ผู้ดูแลระบบผู้ใช้
ศูนย์การจัดการ Teams ผู้ดูแลระบบ Teams จําเป็นหากคุณวางแผนที่จะเปิดใช้งานการรวม Microsoft Teams

ขั้นตอนในการตั้งค่าเอเจนต์ค่าใช้จ่าย

เมื่อต้องการติดตั้งและตั้งค่าเจ้าหน้าที่ค่าใช้จ่าย ให้ทําตามขั้นตอนเหล่านี้:

  1. ติดตั้ง Copilot สําหรับแอปการเงินและการดําเนินงาน
  2. เปิดใช้งานคุณลักษณะของเอเจนต์ในสภาพแวดล้อมของคุณ
  3. สร้างผู้ใช้ค่าใช้จ่ายสําหรับการดําเนินการของเอเจนต์
  4. ตั้งค่ากล่องจดหมายที่ใช้ร่วมกัน
  5. ตั้งค่าเอเจนต์ค่าใช้จ่าย
  6. เปิดใช้งานเอเจนต์ค่าใช้จ่ายใน Microsoft Teams (ไม่บังคับ - หากคุณต้องการการรวม Microsoft Teams)

ส่วนต่อไปนี้อธิบายแต่ละขั้นตอนโดยละเอียด

ขั้นตอนที่ 1: ติดตั้ง Copilot สําหรับแอปการเงินและการดําเนินงาน

เอเจนต์ค่าใช้จ่ายสามารถใช้งานเป็นส่วนหนึ่งของแพคเกจ Copilot สําหรับแอปการเงินและการดำเนินงาน หลังจากที่คุณติดตั้งแพคเกจนี้ในสภาพแวดล้อมของคุณ คุณจะได้รับแอสเซทที่จําเป็นทั้งหมดโดยอัตโนมัติ รวมถึงเจ้าหน้าที่ ตัวแปรสภาพแวดล้อม และโฟลว์ Power Automate

เมื่อต้องการติดตั้งแอปที่จําเป็น ให้ทําตามขั้นตอนเหล่านี้:

  1. ไปที่ ศูนย์การจัดการ Power Platform ในเบราว์เซอร์ของคุณ
  2. จากรายการของสภาพแวดล้อม ให้เลือกชื่อสภาพแวดล้อมที่คุณต้องการติดตั้งแอป
  3. บนหน้ารายละเอียดของสภาพแวดล้อม (ไม่ใช่จากการนําทางด้านซ้าย) ให้ไปที่ส่วน ทรัพยากร และเลือก แอป Dynamics 365
  4. ค้นหา Copilot สําหรับแอปการเงินและการดำเนินงาน ภายในรายการแอป Dynamics 365 หากมีการติดตั้งอยู่แล้วและมีการอัปเดต ให้เลือกปุ่ม อัปเดต
  5. หากแอปไม่ได้แสดงอยู่ภายใต้แอป Dynamics 365 เลือก ติดตั้งแอป เลือก Copilot สําหรับแอปการเงินและการดำเนินงาน และทําตามพร้อมท์เพื่อติดตั้งให้เสร็จสมบูรณ์

Note

เรียนรู้เพิ่มเติมเกี่ยวกับวิธีการเปิดใช้งาน Copilot ในสภาพแวดล้อมของคุณใน เปิดใช้งานความสามารถของ Copilot ในแอปการเงินและการดำเนินงาน

เคล็ดลับ

เมื่อต้องการตรวจสอบว่าแพคเกจได้รับการติดตั้งเรียบร้อยแล้วหรือไม่ ให้ทําตามขั้นตอนเหล่านี้:

  1. ไปที่ Power Apps Maker Portal > เลือกสภาพแวดล้อมของคุณ > เลือก โซลูชัน > ดูประวัติ > ค้นหาและเลือกรายละเอียด msdyn_ExpenseAI >
  2. ตรวจสอบเขตข้อมูลผลลัพธ์
    1. หากผลลัพธ์แสดงเป็นสําเร็จ แสดงว่ามีการติดตั้งแพคเกจอย่างถูกต้อง
    2. หากผลลัพธ์ไม่แสดงเป็นสําเร็จ แสดงว่าการติดตั้งล้มเหลว
  3. หากการติดตั้งล้มเหลว ให้ลบ msdyn_FnOCopilotAnchor (ดูส่วนถอนการติดตั้ง) และติดตั้งแอป Copilot สําหรับการเงินและการดําเนินงานอีกครั้ง

ขั้นตอนที่ 2: เปิดใช้งานคุณลักษณะของเอเจนต์ในสภาพแวดล้อมของคุณ

หลังจากที่คุณติดตั้งแพคเกจแอป Copilot สําหรับการเงินและการดําเนินงานแล้ว ให้เปิดใช้งานตัวแทนค่าใช้จ่ายจากภายในสภาพแวดล้อมข้อมูลและการเงินและการดําเนินงานของคุณ

เปิดใช้งานคุณลักษณะใน Dataverse

เปิดค่าสถานะคุณลักษณะ Copilot ในศูนย์การจัดการ Power Platform เมื่อต้องการเปิดใช้งานค่าสถานะคุณลักษณะ Copilot ให้ทําตามขั้นตอนเหล่านี้:

  1. ไปที่ ศูนย์การจัดการ Power Platform
  2. เลือก สภาพแวดล้อม> เลือกสภาพแวดล้อมของคุณ >การตั้งค่า>ผลิตภัณฑ์> เลือก คุณลักษณะ
  3. ยืนยันว่าค่าสถานะคุณลักษณะ Copilot เปิดอยู่

เปิดใช้งานคุณลักษณะในสภาพแวดล้อมการเงินและการดําเนินงานของคุณ

หากต้องการเปิดใช้งานตัวแทนในแอปการเงินและการดําเนินงาน ให้ทําตามขั้นตอนเหล่านี้:

  1. ลงชื่อเข้าใช้ สภาพแวดล้อมการเงินและการดำเนินงาน ของคุณ
  2. ไปที่ การจัดการคุณลักษณะ และเปิดใช้งาน คุณลักษณะหน้าแรกแบบครอบคลุม และคุณลักษณะ การจัดการเอเจนต์
  3. เมื่อต้องการกําหนดค่าเอเจนต์ค่าใช้จ่าย (การตั้งค่าแบบต่อนิติบุคคล) ไปที่ การจัดการค่าใช้จ่าย>การตั้งค่า>ทั่วไป>พารามิเตอร์การจัดการค่าใช้จ่าย
  4. บนแท็บ เอเจนต์รายการค่าใช้จ่าย ให้กําหนดค่าพารามิเตอร์ตามที่แสดงในตารางต่อไปนี้
พารามิเตอร์ ค่า ความคิดเห็น
เปิดใช้งานเอเจนต์ค่าใช้จ่ายสําหรับนิติบุคคลปัจจุบัน ได้ สลับเป็น ใช่ เพื่อเปิดใช้งานเอเจนต์สําหรับนิติบุคคลปัจจุบัน
ความถี่ รายวันหรือรายสัปดาห์ กําหนดค่าความถี่สําหรับการสร้างรายงานค่าใช้จ่ายในองค์กรของคุณโดยอัตโนมัติ
จัดกลุ่มรายงานตาม การเดินทางหรือโครงการ กําหนดค่าเพื่อจัดกลุ่มค่าใช้จ่ายตามโครงการหรือการเดินทาง

ขั้นตอนที่ 3: สร้างผู้ใช้งานตัวแทนค่าใช้จ่ายสำหรับการดำเนินงานของตัวแทน

สร้างผู้ใช้เอเจนต์ค่าใช้จ่ายเฉพาะเพื่อให้แน่ใจว่าเอเจนต์จะทำงานอย่างอิสระจากข้อมูลประจําตัวของพนักงานใดๆ วิธีนี้ช่วยให้มีความปลอดภัย ความสามารถในการจัดการ และการรักษาไว้ในระยะยาว แม้ว่าคุณจะสามารถใช้บัญชีผู้ใช้ที่มีอยู่ซึ่งมีสิทธิ์ที่ต้องการได้ ให้ใช้ข้อมูลประจําตัวที่ระบบเป็นเจ้าของ

สร้างผู้ใช้ของบริษัทตัวแทนค่าใช้จ่ายใน Microsoft Entra ID

  1. ลงชื่อเข้าใช้ พอร์ทัล Azure
  2. จากบริการ Azure ที่มีอยู่ ให้เลือก Microsoft Entra ID
  3. ภายใต้ Microsoft Entra ID ให้สร้างผู้ใช้ใหม่
  4. เลือก เพิ่ม>ผู้ใช้>สร้างผู้ใช้ใหม่ และป้อนรายละเอียดต่อไปนี้
    • ชื่อหลักของผู้ใช้
    • เลือกโดเมนที่ถูกต้อง
    • ชื่อที่แสดง
    • รหัสผ่าน
    • ทำเครื่องหมายเปิดใช้งานบัญชี
  5. หากต้องการดูรายละเอียดและเสร็จสิ้นกระบวนการสร้างผู้ใช้ ให้เลือก ตรวจสอบและสร้าง และเลือก สร้าง
  6. จากหน้าผู้ใช้ (จัดการ > ผู้ใช้) เลือกผู้ใช้ และหน้ารายละเอียดมุมมอง
  7. เลือก แก้ไขคุณสมบัติ ไปยังแท็บ การตั้งค่า และกรอกข้อมูลตําแหน่งที่ตั้งการใช้งานที่เหมาะสม

Note

คุณอาจจําเป็นต้องเปลี่ยนรหัสผ่านของคุณและตั้งค่าการรับรองความถูกต้องโดยใช้หลายปัจจัย (MFA) ทั้งนี้ขึ้นอยู่กับนโยบายขององค์กรของคุณ ทําตามขั้นตอนตามปกติสําหรับการเปลี่ยนรหัสผ่านและการตั้งค่า MFA

กําหนดสิทธิการใช้งานที่จําเป็นให้กับผู้ใช้เอเจนต์ค่าใช้จ่าย

เมื่อต้องการติดตั้งตัวแทนค่าใช้จ่ายให้เสร็จสมบูรณ์ ให้กําหนดสิทธิ์การใช้งานต่อไปนี้ให้กับผู้ใช้ของบริษัทตัวแทนค่าใช้จ่าย:

  • สิทธิการใช้งาน Dynamics 365 Teams Members
  • Microsoft 365 Business Basic หรือสิทธิการใช้งานใดๆ ที่ครอบคลุม Microsoft Teams และ Outlook (ตัวอย่างเช่น Office 365 E5 ที่มี Teams)
  • Power Apps Premium

เมื่อต้องการมอบหมายสิทธิ์การใช้งาน ให้ทําตามขั้นตอนเหล่านี้:

  1. ลงชื่อเข้าใช้ ศูนย์การจัดการ Microsoft 365 ด้วยผู้ใช้ที่มีสิทธิ์เข้าถึงเพื่อกำหนดสิทธิการใช้งานที่เป็นผู้ใช้ที่มีผู้ดูแลระบบสิทธิการใช้งานหรือสูงกว่า
  2. เลือก การเรียกเก็บเงิน>สิทธิการใช้งาน>สิทธิการใช้งาน Dynamics 365 Teams Members
  3. เลือก +กำหนดสิทธิการใช้งาน
  4. ค้นหาผู้ใช้เอเจนต์ค่าใช้จ่ายที่สร้างขึ้นในขั้นตอนก่อนหน้า
  5. เลือกกําหนดเพื่อดําเนินการกําหนดสิทธิการใช้งานให้เสร็จสมบูรณ์
  6. ทําตามขั้นตอนที่ 2 ถึง 5 สําหรับสิทธิการใช้งานอื่นๆ – Microsoft 365 Business Basic และ Power Apps Premium ได้เช่นกัน

Note

เรียนรู้เพิ่มเติมเกี่ยวกับวิธีการตรวจสอบและกำหนดสิทธิการใช้งานใน ใช้หน้าผู้ใช้ที่ใช้งานอยู่เพื่อกําหนดหรือยกเลิกการกำหนดสิทธิการใช้งาน

เพิ่มผู้ใช้ในสภาพแวดล้อม Power Platform

หากต้องการเพิ่มผู้ใช้ไปยังสภาพแวดล้อม Power Platform ให้ทําตามขั้นตอนเหล่านี้:

  1. ลงชื่อเข้าใช้ ศูนย์การจัดการ Power Platform และเลือกสภาพแวดล้อมที่เหมาะสม

    เคล็ดลับ

    หน้านี้มีข้อมูลที่เกี่ยวข้องกับ ID สภาพแวดล้อมสําหรับ Dataverse, URL ของสภาพแวดล้อมสําหรับ Dataverse, URL ของการเงินและการดำเนินงาน จัดเก็บค่าเหล่านี้เพื่อใช้ในส่วนต่อๆ ไป

  2. ไปที่ การเข้าถึง > ผู้ใช้ > ดูทั้งหมด

  3. เลือก เพิ่มผู้ใช้ ป้อนผู้ใช้เอเจนต์ที่สร้างขึ้นใหม่ และเลือก เพิ่ม

  4. บนหน้า จัดการบทบาทความปลอดภัย ให้เพิ่มบทบาทต่อไปนี้

    • บทบาทเอเจนต์ AI ด้านค่าใช้จ่าย
    • ตัวจัดการการกําหนดค่าเอเจนต์การเงินและการดำเนินงาน
    • ผู้กำหนดค่าระบบ
  5. เมื่อต้องการยืนยันการกําหนดบทบาท ให้เลือก บันทึก

บทบาทเหล่านี้ให้การเข้าถึง Dataverse และคอมโพเนนต์ Power Automate ที่เอเจนต์ต้องการในการทํางาน

เคล็ดลับ

หากผู้ใช้มีอยู่แล้วและคุณจําเป็นต้องกําหนดบทบาทเท่านั้นให้ไปที่ ศูนย์การจัดการ Power Platform และเลือกสภาพแวดล้อมที่เหมาะสม

  1. ไปที่ การเข้าถึง > ผู้ใช้ > ดูทั้งหมด
  2. เลือกผู้ใช้เอเจนต์ที่สร้างขึ้น
  3. เลือก จัดการบทบาท และกําหนดบทบาท

กําหนดบทบาทที่จําเป็นในสภาพแวดล้อมการเงินและการดําเนินงาน

เพื่อกําหนดบทบาท ExpenseAgentRole ในสภาพแวดล้อมการเงินและการดําเนินงาน ให้ทําตามขั้นตอนเหล่านี้:

  1. ในสภาพแวดล้อมการเงินและการดําเนินงาน ไปที่ การดูแลระบบ>ผู้ใช้
  2. สร้างเรกคอร์ดผู้ใช้สําหรับผู้ใช้เอเจนต์
  3. หลังจากสร้างผู้ใช้แล้ว ให้ไปที่ส่วนบทบาทของผู้ใช้ เลือก กําหนดบทบาท และค้นหา ExpenseAgentRole
  4. เลือก บันทึก

Note

ExpenseAgentRole มีให้ใช้งานในเวอร์ชันแอปการเงินและการดําเนินงานจาก 10.0.44 (10.0.2263.81) และ 10.0.45 (10.0.2345.6) และที่มี Copilot สำหรับแอปการเงินและการดำเนินงาน เวอร์ชัน 1.0.3121.1

กําหนดการเข้าถึงให้กับการเข้าถึงกล่องจดหมายที่ใช้ร่วมกัน

ผู้ใช้เอเจนต์ต้องมีสิทธิ์ Mail.Read.Shared Microsoft Graph สิทธิ์นี้ช่วยให้เอเจนต์สามารถอ่านใบเสร็จจากกล่องจดหมายที่ใช้ร่วมกันที่กำหนดค่าไว้ระหว่างการดําเนินการของโฟลว์

เมื่อต้องการกําหนดการเข้าถึงกล่องจดหมายที่ใช้ร่วมกัน ให้ทําตามขั้นตอนเหล่านี้:

  1. ไปที่ Microsoft Graph Explorer และลงชื่อเข้าใช้โดยใช้ผู้ใช้ตัวแทนที่สร้างขึ้น
  2. เลือกไอคอน ผู้ใช้ ที่มุมขวาบน > เลือก ยินยอมให้สิทธิ์
  3. เลือกเมนูดรอปดาวน์สําหรับ จดหมาย> ค้นหา Mail.Read.Shared> เลือก ความยินยอม แล้วเลือก ยอมรับ

ข้อมูลสรุปของบทบาทที่ต้องการสําหรับผู้ใช้เอเจนต์ที่สร้างขึ้น

Environment บทบาท ความคิดเห็น
Dataverse
  • บทบาทเอเจนต์ AI สำหรับค่าใช้จ่าย
  • ตัวจัดการการกําหนดค่าเอเจนต์การเงินและการดำเนินงาน
  • ผู้กำหนดค่าระบบ
  • บทบาทที่กล่าวถึงช่วยให้เอเจนต์สามารถโต้ตอบกับโฟลว์ Power Automate, ตัวแปรสภาพแวดล้อม และเอนทิตีเสมือนที่เชื่อมต่อกับ Dynamics 365 Finance
    Finance and Operations
  • ExpenseAgentRole
  • ผู้ใช้ของระบบ
  • บทบาทนี้จําเป็นสําหรับเอเจนต์ในการสร้างและจัดการรายการค่าใช้จ่ายในสภาพแวดล้อมแอปการเงินและการดำเนินงาน

    หมายเหตุ: ExpenseAgentRole มีให้ใช้งานในเวอร์ชันแอปการเงินและการดําเนินงานจาก 10.0.44 (10.0.2263.81) และ 10.0.45 (10.0.2345.6) และที่มี Copilot สำหรับแอปการเงินและการดำเนินงาน เวอร์ชัน 1.0.3121.1
    การเข้าถึงกล่องจดหมายที่ใช้ร่วมกันโดยใช้ตัวสํารวจ Graph Mail.Read.Shared สิทธิ์ของ Microsoft Graph ที่ให้เอเจนต์สามารถอ่านใบเสร็จจากกล่องจดหมายที่ใช้ร่วมกันที่กำหนดค่าไว้ระหว่างการดําเนินการของโฟลว์

    ขั้นตอนที่ 4: ตั้งค่ากล่องจดหมายที่ใช้ร่วมกัน

    เอเจนต์ค่าใช้จ่ายใช้กล่องจดหมายที่ใช้ร่วมกันเพื่อรับและประมวลผลอีเมลใบเสร็จ ผู้ใช้ที่มีบทบาทผู้ดูแลระบบ Exchange จําเป็นต้องสร้างและกําหนดค่ากล่องจดหมายนี้ในศูนย์การจัดการ Microsoft 365

    เมื่อต้องการสร้างและกําหนดค่ากล่องจดหมายที่ใช้ร่วมกัน ให้ทําตามขั้นตอนเหล่านี้:

    1. ลงชื่อเข้าใช้ ศูนย์การจัดการ Microsoft 365 โดยใช้บัญชีผู้ดูแลระบบ Exchange

    2. ในบานหน้าต่างด้านซ้าย ให้เลือก ทีม & กลุ่ม>กล่องจดหมายที่ใช้ร่วมกัน

      เคล็ดลับ

      คุณอาจจําเป็นต้องเลือก แสดงทั้งหมด เพื่อขยายรายการทั้งหมด

    3. เลือก เพิ่มกล่องจดหมายที่แชร์

    4. ป้อนชื่อและที่อยู่อีเมลสําหรับกล่องเมลที่แชร์

    5. เลือก บันทึกการเปลี่ยนแปลง

    6. ภายใต้ ขั้นตอนถัดไป เลือก เพิ่มสมาชิกในกล่องจดหมายที่ใช้ร่วมกันนี้ (การจัดการสมาชิกอาจใช้เวลาสักครู่เพื่อให้พร้อมใช้งาน)

    7. เลือก เพิ่มสมาชิก

    8. เลือกผู้ใช้เอเจนต์ที่สร้างขึ้นและบุคคลอื่นที่ควรตรวจสอบกล่องจดหมาย และเลือก เพิ่ม

    9. เลือก ปิด

    Note

    คุณใช้ที่อยู่อีเมลของกล่องจดหมายที่แชร์ในขั้นตอนถัดไป หลังจากที่คุณตั้งค่ากล่องจดหมายที่แชร์แล้ว คุณต้องระบุที่อยู่อีเมลและเส้นทางโฟลเดอร์ (ตามค่าเริ่มต้นที่ตั้งค่าเป็นกล่องขาเข้า) เป็นตัวแปรสภาพแวดล้อมเมื่อคุณกําหนดค่า Time และ Expense Agent สําหรับข้อมูลเพิ่มเติม โปรดดูขั้นตอนที่ 5: ตั้งค่าตัวแทนค่าใช้จ่าย

    ขั้นตอนที่ 5: ตั้งค่าเอเจนต์ค่าใช้จ่าย

    คุณมีสองตัวเลือกสําหรับการตั้งค่าเอเจนต์ค่าใช้จ่าย:

    • ตัวเลือก A: ใช้สคริปต์ PowerShell (แนะนํา)
    • ตัวเลือก B: ตั้งค่าด้วยตนเองใน Power Apps (ไม่มี PowerShell)

    สําคัญ

    ก่อนดําเนินการติดตั้งตัวแทนค่าใช้จ่ายตรวจสอบให้แน่ใจว่าตัวแทนถูกเตรียมใช้งานเรียบร้อยแล้วใน Microsoft Copilot Studio

    เมื่อต้องการตรวจสอบว่าตัวแทนถูกเตรียมใช้งานเรียบร้อยแล้ว ให้ทําตามขั้นตอนเหล่านี้:

    1. ลงชื่อเข้าใช้ Microsoft Copilot Studio และเลือกสภาพแวดล้อมของคุณ
    2. ไปที่ เอเจนต์ และค้นหา ExpenseAgent-Line (พรีวิว)
    3. ตรวจสอบปุ่ม เผยแพร่ ถูกเปิดใช้งาน
    4. หากเปิดใช้งาน ให้ดําเนินการติดตั้งต่อ ถ้าปิดใช้งาน ให้รอจนกว่าจะมีการเตรียมใช้งานเอเจนต์
    5. ทําซ้ำขั้นตอนเหล่านี้เพื่อตรวจสอบว่ามีการเปิดใช้งาน เอเจนต์รายการค่าใช้จ่าย (พรีวิว)

    เคล็ดลับ

    ถ้าการเตรียมใช้งานแอปการเงินและการดําเนินงาน Copilot ใช้เวลานานกว่า 5-6 ชั่วโมง ให้ถอนการติดตั้งและติดตั้งแอปใหม่เพื่อแก้ไขปัญหาความล่าช้าในการตั้งค่าที่อาจเกิดขึ้น สําหรับข้อมูลเพิ่มเติม ดูส่วน ถอนการติดตั้งเจ้าหน้าที่ค่าใช้จ่าย ที่ส่วนท้ายของบทความนี้

    การตั้งค่าเอเจนต์ด้วยตนเองเกี่ยวข้องกับการสร้างและเชื่อมโยงการเชื่อมต่อ การเปิดใช้งานโฟลว์ Power Automate และการเผยแพร่โซลูชัน กระบวนการนี้อาจใช้เวลานานและมีความเสี่ยงที่จะเกิดข้อผิดพลาด หากต้องการทําการตั้งค่าให้เป็นอัตโนมัติ ให้ใช้สคริปต์ PowerShell หลังจากอัปเดตพารามิเตอร์ที่จําเป็นแล้ว

    สคริปต์ PowerShell ทํางานต่อไปนี้โดยอัตโนมัติ:

    • อัปเดตตัวแปรสภาพแวดล้อมที่จําเป็น
    • เชื่อมโยงการเชื่อมต่อ Microsoft Power Platform กับการอ้างอิงการเชื่อมต่อโซลูชัน
    • เปิดใช้งานโฟลว์ Power Automate ทั้งหมดที่ เอเจนต์เวลาและค่าใช้จ่ายต้องการ
    • เผยแพร่ตัวแทน Copilot
    • เผยแพร่โซลูชัน Dataverse

    ก่อนที่จะเรียกใช้สคริปต์ คุณจําเป็นต้อง สร้างการเชื่อมต่อ ตามที่คุณต้องการเพื่อระบุ ID การเชื่อมต่อสําหรับตัวเชื่อมต่อแต่ละรายการในไฟล์ install.ps1 เมื่อต้องสร้างการเชื่อมต่อเหล่านี้ ทําตามขั้นตอนเหล่านี้โดยใช้ผู้ใช้ตัวแทนที่สร้างขึ้น

    1. ลงชื่อเข้าใช้ พอร์ทัล Power Apps Maker โดยใช้ผู้ใช้ของบริษัทตัวแทนที่สร้างขึ้นใหม่ และเลือกสภาพแวดล้อมของคุณ
    2. ในบานหน้าต่างด้านซ้าย เลือก เพิ่มเติม และเลือก การเชื่อมต่อ
    3. เลือก การเชื่อมต่อใหม่ และค้นหาโดยใช้ ชื่อการเชื่อมต่อ จากตารางต่อไปนี้ (ตัวอย่างเช่น Office 365 Outlook)
    4. เลือกตัวเชื่อมต่อที่เหมาะสมจากรายการและสร้าง
    5. เมื่อสร้างการเชื่อมต่อแล้ว ให้บันทึกผู้ใช้ที่สร้างการเชื่อมต่อด้วย ควรเป็น ID ผู้ใช้เอเจนต์ที่สร้างขึ้น อัปเดต ID ผู้ใช้นี้ในไฟล์การติดตั้งที่คุณสร้างในขั้นตอนถัดไป
    6. ทําซ้ำขั้นตอนที่ 3 และ 4 สําหรับการเชื่อมต่อที่จําเป็นแต่ละรายการที่เหลือที่แสดงในตารางต่อไปนี้
    ชื่อของการเชื่อมต่อ รูปแบบ URL การเชื่อมต่อ
    Office 365 Outlook https://make.powerapps.com/environments/environmentID/connections
    / shared_office365/connectionID/details
    ผู้ใช้ Office 365 https://make.powerapps.com/environments/environmentID/connections
    / shared_office365users/connectionID/details
    ทีมไมโครซอฟท์ https://make.powerapps.com/environments/environmentID/connections
    / shared_teams/connectionID/details
    ไมโครซอฟท์ ดาต้าเวิร์ส https://make.powerapps.com/environments/environmentID/connections
    / shared_commondataserviceforapps/connectionID/details
    Microsoft Copilot Studio (พรีวิว) https://make.powerapps.com/environments/environmentID/connections
    / shared_microsoftcopilotstudio/connectionID/details

    ข้อมูลที่คุณต้องการในการสร้างไฟล์การติดตั้ง

    เมื่อต้องการสร้างแฟ้มการติดตั้ง - install.ps1มีข้อมูลต่อไปนี้ที่พร้อมใช้งาน (คุณสามารถอ้างอิงไปยังตารางต่อไปนี้)

    พารามิเตอร์ รายละเอียดอื่นๆ
    ID สภาพแวดล้อม Dataverse ป้อน ID สภาพแวดล้อมที่คุณได้รับจากศูนย์การจัดการ Power Platform
    ค่าตัวอย่าง: xxxx-xxxx-xxxx-xxx-xxxxxxxxxx
    URL สภาพแวดล้อม Dataverse ป้อน URL สภาพแวดล้อมจากศูนย์การจัดการ Power Platform
    หมายเหตุ: ตรวจสอบให้แน่ใจว่ามี https:// ที่ส่วนเริ่มต้นและไม่มีเครื่องหมายขีดทับ ‘/’ ที่ส่วนท้าย
    ค่าตัวอย่าง: https://org123.crm.contoso.com
    URL อินสแตนซ์การเงินและการดำเนินงาน ป้อนรายละเอียดสภาพแวดล้อมการเงินและการดําเนินงานในรูปแบบต่อไปนี้
    ค่าตัวอย่าง: https://org123.contoso.com
    หมายเหตุ: ตรวจสอบให้แน่ใจว่า มี https:// ที่ส่วนเริ่มต้นและ ไม่มี เครื่องหมายขีดทับ ‘/’ ที่ส่วนท้าย
    OutlookFolderPath ใส่พาธของโฟลเดอร์ที่สร้างขึ้นในกล่องจดหมายที่ใช้ร่วมกัน หากไม่มีการสร้างโฟลเดอร์อื่น จะมีการตั้งค่าเป็นกล่องขาเข้าตามค่าเริ่มต้น
    ค่าตัวอย่าง: กล่องขาเข้า
    แนวทางปฏิบัติที่ดีที่สุดคือสร้างโฟลเดอร์แยกต่างหากสําหรับการจัดการค่าใช้จ่าย
    ID ที่อยู่กล่องจดหมาย กรอกที่อยู่อีเมลของกล่องจดหมายที่ใช้ร่วมกันซึ่งสร้างขึ้นใหม่
    ค่าตัวอย่าง: expenseagent@contoso.com
    ชื่อการเชื่อมต่อ Microsoft Dataverse
    ชื่อการเชื่อมต่อ Microsoft Copilot Studio
    ชื่อการเชื่อมต่อ Microsoft Office Outlook
    ชื่อการเชื่อมต่อผู้ใช้ Microsoft Office 365
    ชื่อการเชื่อมต่อ Microsoft Teams
    อินพุตสําหรับชื่อการเชื่อมต่อทั้งหมดเหมือนกันและเป็นรหัสอีเมลของผู้ใช้ตัวแทนที่สร้างขึ้น

    ค่าตัวอย่าง: createdexpenseagentuser@contoso.com

    สร้างไฟล์สคริปต์การติดตั้ง

    สร้างไฟล์สคริปต์การติดตั้งโดยการคัดลอกโค้ดต่อไปนี้ แทรกตัวแปรสภาพแวดล้อมที่จําเป็นลงในสคริปต์ จากนั้นเรียกใช้สคริปต์โดยใช้ PowerShell

    Note

    วางไฟล์สคริปต์การติดตั้งบนเดสก์ท็อปภายในเครื่อง อย่าจัดเก็บไว้ใน One Drive

    สร้างไฟล์สคริปต์ PowerShell ด้วยโค้ดต่อไปนี้ อัปเดตพารามิเตอร์ที่กล่าวถึงก่อนที่จะเรียกใช้สคริปต์

    เคล็ดลับ

    เมื่อ จําเป็น = $true PowerShell จะพร้อมท์ให้คุณใส่พารามิเตอร์แบบโต้ตอบ ดังนั้นคุณไม่จําเป็นต้องอัปเดตโดยตรงในไฟล์สคริปต์

    หากคุณต้องการหลีกเลี่ยงการป้อนข้อมูลด้วยตนเองและต้องการกําหนดพารามิเตอร์ไว้ล่วงหน้าภายในสคริปต์การติดตั้ง ให้ตั้งค่า ข้อบังคับ = $false ในส่วน Param ของโค้ดตัวอย่างต่อไปนี้

    คัดลอกโค้ดต่อไปนี้ลงในไฟล์สคริปต์การติดตั้งและบันทึกเป็น 'Install.ps1' อัปเดตตัวแปรในเขตข้อมูลพารามิเตอร์ที่เกี่ยวข้อง ในส่วนพารามิเตอร์ คุณจําเป็นต้องอัปเดต 10 ตัวแปร

    เคล็ดลับ

    ใช้ตารางก่อนหน้าเป็นข้อมูลอ้างอิงและแทนที่ค่าตัวอย่างทั้งหมดด้วยรายละเอียดที่เกี่ยวข้องของคุณ

    #requires -Version 7
    Param(
    
       [Parameter(Mandatory=$true, HelpMessage="Dataverse environment id")]
       [string]$DataverseEnvironmentId = "xxxx-xxxx-xxxx-xxx-xxxxxxxxxx", 
    
       [Parameter(Mandatory=$true, HelpMessage="Dataverse environment URL")]
       [string]$DataverseUrl = "https://org123.crm.dynamics.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Finance and Operations instance URL")]
       [string]$D365FinanceAndOperationsUrl = "https://org123.operations.dynamics.com",
    
       [Parameter(Mandatory=$true, HelpMessage="OutlookFolderPath")]
       [string]$OutlookFolderPath = "Inbox",
    
       [Parameter(Mandatory=$true, HelpMessage="Mailbox Address Id")]
       [string]$MailboxAddressId = "expenseagent@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Dataverse connection name")]
       [string]$MicrosoftDataverseConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Copilot Studio connection name")]
       [string]$MicrosoftCopilotStudioConnectionName = "createdexpenseagentuser@contoso.com",
       
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Office Outlook connection name")]
       [string]$Office365OutlookConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Office 365 Users connection name")]
       [string]$Office365UsersConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Teams connection name")]
       [string]$MicrosoftTeamsConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$false, HelpMessage="Checks for bot Sync Errors and if there is provisioning required before Agent publish step")]
       [boolean]$CheckBotSyncStatusAndProvisionBots = $false
    
    )
    
    $flows = @(
        "expense entry retry check",
        "expense configuration",
        "get expense outlook folder",
        "generate expense report",
        "send expense report adaptive card",
        "auto match expenses",
        "process emails",
        "extract unattached receipt ids for copilot invocation",
        "extract unattached receipt output using dataverse plugin",
        "generate expense line",
        "generate expense line without project id and status id",
        "identify project ids",
        "user calendar events",
        "process expense report using copilot",
        "invoke expense agent for receipt processing"
    )
    
    
    $agents = @(
        "msdyn_ExpenseEntryAgent",
        "msdyn_ExpenseReportAgent"
    )
    
    
    # Check PS version
    if ($PSVersionTable.PSVersion.Major -lt 7) {
        Write-Error 'This script requires at least PowerShell version 7' -ErrorAction Stop
    }
    
    # Install the required modules if not already installed or if the version is not 1.0.40
    if (-not (Get-Module -ListAvailable -Name Microsoft.PowerApps.PowerShell | Where-Object { $_.Version -ge [Version]"1.0.40" })) {
        Write-Host "Microsoft.PowerApps.PowerShell version 1.0.40 not found. Installing..." -ForegroundColor Yellow
        Install-Module -Name Microsoft.PowerApps.PowerShell -RequiredVersion 1.0.40 -Force -AllowClobber -Scope CurrentUser
    } else {
        Write-Host "Microsoft.PowerApps.PowerShell version 1.0.40 is already installed." -ForegroundColor Green
    }
    
    if (-not (Get-Module -ListAvailable -Name Microsoft.PowerApps.Administration.PowerShell | Where-Object { $_.Version -ge [Version]"2.0.147" })) {
        Install-Module -Name Microsoft.PowerApps.Administration.PowerShell -RequiredVersion 2.0.147 -Force -AllowClobber -Scope CurrentUser
    }
    
    # Install the required modules if not already installed
    if (-not (Get-Module -ListAvailable -Name Az.Accounts | Where-Object { $_.Version -ge [Version]"5.0.1"})) {
        Install-Module -Name Az.Accounts -RequiredVersion 5.0.1 -Force -AllowClobber -Scope CurrentUser
    }
    
    # Import required modulesds
    Import-Module Az.Accounts
    Import-Module Microsoft.PowerApps.PowerShell
    Import-Module Microsoft.PowerApps.Administration.PowerShell
    
    # global variable declaration
    $filter = '$filter'
    
    
    function Get-AccessToken {
        # Retrieve the access token for the Dataverse environment
        $accessToken = (Get-AzAccessToken -ResourceUrl "$DataverseUrl" -AsSecureString).Token
        Write-Host "Access token for $userId retrieved successfully." -ForegroundColor Green
        return $accessToken
    }
    
    function Get-AccessTokenPlainText {
        param(
            [Parameter(Mandatory=$true, HelpMessage="Access token for authentication")]
            [securestring]$accessToken
        )
        # Retrieve the access token for the PVA environment
        $token = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
        [Runtime.InteropServices.Marshal]::SecureStringToBSTR($accessToken))
        return $token
    }
    
    function update-EnvironmentVaribleValue {
            param (
            [string]$accessToken,
            [string]$env_key,
            [string]$env_value   # Access token for authentication
        )
    
        try 
        {
            # Get the environment variable definition
            $envVarDefinition = Invoke-RestMethod -Method Get -Uri "$DataverseUrl/api/data/v9.2/environmentvariabledefinitions?$filter=schemaname eq '$env_key'" -Headers @{
                Authorization = "Bearer $accessToken"
            }
    
            if ($envVarDefinition.value -ne $null) {
                $envVarDefId = $envVarDefinition.value[0].environmentvariabledefinitionid
    
                # Get the environment variable value record
                $filterValue = [System.Web.HttpUtility]::UrlEncode("_environmentvariabledefinitionid_value eq $envVarDefId")
                $envVarValue = Invoke-RestMethod -Method Get -Uri "$DataverseUrl/api/data/v9.2/environmentvariablevalues?$filter=$filterValue" -Headers @{
                    Authorization = "Bearer $accessToken"
                }
    
                if ($envVarValue.value -ne $null) {
                    $envVarValueId = $envVarValue.value[0].environmentvariablevalueid
                    # Update the environment variable value
                    Invoke-RestMethod -Method Patch -Uri "$DataverseUrl/api/data/v9.2/environmentvariablevalues($envVarValueId)" -Headers @{
                        Authorization = "Bearer $accessToken"
                        "Content-Type" = "application/json"
                    } -Body (@{ value = $env_value } | ConvertTo-Json -Depth 1)
                    Write-Host "Environment variable updated with name $env_key and value $env_value" -ForegroundColor Green
                } else {
                    Write-Host "Environment variable value not found for $env_key. Skipping..." -ForegroundColor Red
                }
            } 
            else {
                Write-Host "Environment variable definition not found for $env_key. Skipping..." -ForegroundColor Yellow
            }
      }
      catch {
            Write-Host "Failed to update environment variable $env_key. Error: $($_)" -ForegroundColor Red
            throw $_  # Re-throw the error to stop the script if this step is critical
        }
    
    }
    
    function update_EnvironmentVariablesForExpense {
            param (
            [string]$accessToken   # Access token for authentication
        )
    
        write-host "Updating environment variables..." -ForegroundColor Yellow
    
        try 
        {
            update-EnvironmentVaribleValue -accessToken $accessToken -env_key "msdyn_ExpenseFnoInstanceUrl" -env_value $D365FinanceAndOperationsUrl
            update-EnvironmentVaribleValue -accessToken $accessToken -env_key "msdyn_ExpenseAgentOutlookFolderPath" -env_value $OutlookFolderPath
            update-EnvironmentVaribleValue -accessToken $accessToken -env_key "msdyn_ExpenseAgentMailboxAddressId" -env_value $MailboxAddressId
            
        }
        Catch {
            Write-Host "Failed to update environment variables. Error: $($_)" -ForegroundColor Red -ErrorAction Stop
        }
    }
    
    # Function to publish the solution
    function Publish-Solution {
        param (
            [string]$accessToken
        )
    
        Write-Host "Publishing All" -ForegroundColor Yellow
    
        # Construct the API endpoint for publishing the solution
        $uri = "$DataverseUrl/api/data/v9.2/PublishAllXml"
    
    
        # Make the API call
        try {
            Invoke-RestMethod -Method Post `
                -Uri $uri `
                -Headers @{
                    Authorization = "Bearer $accessToken"
                    "Content-Type" = "application/json"
                }
    
            Write-Host "Publish All - Success!" -ForegroundColor Green
        } catch {
            Write-Host "Failed to publish. Error: $($_.Exception)" -ForegroundColor Red
            
        }
    }
    
    function Get-FlowGuidByName {
        param (
            [string]$accessToken,   # Access token for authentication
            [string]$flowName       # Name of the flow to search for
        )
    
        #Write-Host "Retrieving GUID for flow: $flowName" -ForegroundColor Yellow
    
        # Construct the API endpoint with a filter for the flow name
        $encodedFlowName = [System.Web.HttpUtility]::UrlEncode($flowName)
        $uri = "$DataverseUrl/api/data/v9.2/workflows?$filter=name eq '$encodedFlowName'"
    
        try {
            # Make the API call
            $response = Invoke-RestMethod -Method Get `
                -Uri $uri `
                -Headers @{
                    Authorization = "Bearer $accessToken"
                    "Content-Type" = "application/json"
                }
    
            # Check if the flow was found
            if ($response.value.Count -gt 0) {
                $flow = $response.value[0]
                Write-Host "Flow found: $($flow.name) with GUID: $($flow.workflowid)" -ForegroundColor Green
                return $flow.workflowid
            } else {
                Write-Host "No flow found with the name: $flowName" -ForegroundColor Red
                return $null
            }
        } catch {
            Write-Host "Failed to retrieve flow GUID. Error: $($_.Exception.Message)" -ForegroundColor Red
            return $null
        }
    }
    
    
    # Function to activate a Power Automate flow
    function Activate-Flow {
        param (
            [string]$DataverseUrl,  # Dataverse environment URL
            [string]$accessToken,   # Access token for authentication
            [string]$flowId         # GUID of the flow to activate
        )
    
        # Construct the request body
        $body = @{
            "statecode" = 1  # Activated
            "statuscode" = 2 # Activated
        } | ConvertTo-Json -Depth 1 -Compress
    
        # Construct the API endpoint
        $uri = "$DataverseUrl/api/data/v9.2/workflows($flowId)"
    
        # Make the API call
        try {
            Invoke-RestMethod -Method Patch `
                -Uri $uri `
                -Headers @{
                    Authorization = "Bearer $accessToken"
                    "Content-Type" = "application/json"
                } `
                -Body $body
    
            Write-Host "Flow activated successfully." -ForegroundColor Green
        } catch {
            Write-Host "Failed to activate flow. Error: $($_.Exception.Message)" -ForegroundColor Red
        }
    }
    
    function Get-ConnectionRefIdFromLogicalName  {
        param (
            [string]$accessToken,
            [string]$connectionRefLogicalName
        )
        $uri = "$DataverseUrl/api/data/v9.2/connectionreferences?$filter=connectionreferencelogicalname eq '$connectionRefLogicalName'"
        $response = Invoke-RestMethod -Method Get `
        -Uri $uri `
        -Headers @{
            Authorization = "Bearer $accessToken"
            "Content-Type" = "application/json"
        }
    
        if ($response -ne $null) {
            write-host "Connection reference id found: $($response.value[0].connectionreferenceid) " -ForegroundColor Green
            return $response.value[0].connectionreferenceid
        }
        else {
            Write-Host "No connection reference found for logical name: $connectionRefLogicalName" -ForegroundColor Red
            return $null
        }
    }
    
    function Get-ConnectionId {
        param (
            [string]$userProvidedName,
            [string]$providerName
        )
    
        try {
            $matchedConnectionId = $null
            # Added -ErrorAction Stop to ensure the catch block is triggered on failure
            $connections = Get-PowerAppConnection -EnvironmentName $DataverseEnvironmentId -ConnectorNameFilter $providerName -ErrorAction Stop
            
            foreach ($con in $connections) {
                if (($con.ConnectionName -eq $userProvidedName) -or ($con.DisplayName -eq $userProvidedName)) {
                    $matchedConnectionId = $con.ConnectionName
                    break
                }
            }
    
            if ($null -eq $matchedConnectionId) {
                # Use 'throw' to create a terminating error that the calling function can catch
                throw "Unable to find connection '$userProvidedName' for provider '$providerName'."
            }
    
            return $matchedConnectionId
        }
        catch {
            # Catch any errors from Get-PowerAppConnection or the 'throw' statement above
            Write-Error "Failed to get connection ID for '$userProvidedName'. Error: $_"
            throw # Re-throw the error to stop the script if this step is critical
        }
    }
    
    function Get-ConnectionReferenceId {
        param(
            [string]$connectionReferenceLogicalName,
            [securestring]$accessToken
        )
    
        try {
            $uri = "$DataverseUrl/api/data/v9.2/connectionreferences?$filter=connectionreferencelogicalname eq '$connectionReferenceLogicalName'"
            
            # Added -ErrorAction Stop for clarity, though Invoke-RestMethod often terminates on HTTP errors
            $response = Invoke-RestMethod -Method Get -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -ErrorAction Stop
                
            if ($null -eq $response -or $response.value.Count -eq 0) {
                throw "Connection reference not found for logical name '$connectionReferenceLogicalName'."
            }
    
            $connectionReferenceDisplayName = $response.value[0].connectionreferencedisplayname
            $connectionReferenceId = $response.value[0].connectionreferenceid
    
            Write-Host "updating connection $connectionReferenceDisplayName for logical name $connectionReferenceLogicalName)"
            return $connectionReferenceId
        }
        catch {
            Write-Error "Failed to get connection reference ID for '$connectionReferenceLogicalName'. Error: $_"
            throw # Re-throw to notify the calling function
        }
    }
    
    function Set-ConnectionReferenceConnection {
        param (
            [string]$connectionReferenceLogicalName,
            [string]$userProvidedConnectionName,
            [string]$providerName,
            [securestring]$accessToken
        )
    
        try {
    
            # These functions will now throw terminating errors if they fail
            $connectionReferenceId = Get-ConnectionReferenceId -connectionReferenceLogicalName $connectionReferenceLogicalName -accessToken $accessToken
            $connectionId = Get-ConnectionId -userProvidedName $userProvidedConnectionName -providerName $providerName
    
            $body = @{
                "connectionid" = "$connectionId"
            } | ConvertTo-Json -Depth 1
    
            $uri = "$DataverseUrl/api/data/v9.2/connectionreferences($connectionReferenceId)"
            # Write-Host "Updating connection reference URI: $uri with connection id $connectionId"
    
            Invoke-RestMethod -Method Patch -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body -ErrorAction Stop
        
            Write-Host "Connection reference updated successfully." -ForegroundColor Green
        }
        catch {
            # This block will catch errors from any of the functions called within the try block
            Write-Error "Failed to set connection reference for '$connectionReferenceLogicalName'. Error: $_"
            throw
        }
    }
    
    function Activate-Flows {
        param (
            [string]$accessToken,
            [array]$expenseAIFlows
        )
    
        foreach ($flowName in $expenseAIFlows) {
             Write-Host "Activating flow: $flowName" -ForegroundColor Yellow
    
            # Call the Get-FlowGuidByName function to get the flow GUID
            $flowGuid = Get-FlowGuidByName -dataverseUrl $DataverseUrl -accessToken $accessToken -flowName $flowName
    
            if ($flowGuid -ne $null) {
                # Write-Host "Flow Name: $flowName, Flow GUID: $flowGuid" -ForegroundColor Green
                Activate-Flow -dataverseUrl $DataverseUrl -accessToken $accessToken -flowId $flowGuid
                # Write-Host "Flow Name: $flowName, Flow GUID: $flowGuid Activated" -ForegroundColor Green
            } else {
                Write-Host "Flow Name: $flowName not found." -ForegroundColor Red
            }
        }
    }
    
    
    # Function to retrieve the Agent ID by name
    function Get-AgentIdBySchemaName {
        param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$agentSchemaName
        )
    
        Write-Host "Retrieving agent ID for agent schema: $agentSchemaName" -ForegroundColor Yellow
    
        # Construct the API endpoint to retrieve the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots?$filter=schemaname eq '$agentSchemaName'"
    
        try {
            # Make the API call
            $response = Invoke-RestMethod -Method Get -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            if ($response.value.Count -gt 0) {
                $agentId = $response.value[0].botid
                return $agentId
            } else {
                Write-Host "No agent found with the name: $agentSchemaName" -ForegroundColor Red
                return $null
            }
        } catch {
            Write-Host "Failed to retrieve agent ID. Error: $($_)" -ForegroundColor Red
            return $null
        }
    }
    
    function Check-BotSyncErrors {
            param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$botId
        )
    
        Write-Host "Retrieving Sync Status for bot ID: $botId" -ForegroundColor Yellow
    
        # Construct the API endpoint to retrieve the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots($botId)"
        try {
            # Make the API call
            $response = Invoke-RestMethod -Method Get -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            if ($null -ne $response.synchronizationstatus) {
                # Parse the JSON string in synchronizationstatus
                $syncStatusObj = $response.synchronizationstatus | ConvertFrom-Json
                $state = $syncStatusObj.currentSynchronizationState.state
                $provisioningStatus = $syncStatusObj.currentSynchronizationState.provisioningStatus
    
                Write-Host "Synchronization State: $state" -ForegroundColor Green
                Write-Host "Provisioning Status: $provisioningStatus" -ForegroundColor Green
    
                if ( $state -contains "Error" -or $provisioningStatus -contains "Error") {
                    Write-Host "Bot has synchronization errors." -ForegroundColor Red
                    return 0
                } else {
                    if ( $state -eq "Synchronized" -or $state -eq 'Synchronizing' -and ($provisioningStatus -eq  "Provisioned" -or $provisioningStatus -eq  "ProvisionedWithoutRegistration")) {
                        Write-Host "Bot synchronization is done." -ForegroundColor Yellow
                        return 1
                    } else {
                        Write-Host "Bot synchronization is in progress." -ForegroundColor Green
                        return 2
                    }
                }
            } else {
                Write-Host "No synchronization status found for bot ID: $botId" -ForegroundColor Red
                return $null
            }
        } catch {
            Write-Host "Failed to retrieve agent ID. Error: $($_)" -ForegroundColor Red
            return $null
        }
    }
    
    
    # Function to provision a PVA bot
    function Provision-Agent {
        param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$agentId
        )
    
        # Construct the API endpoint for publishing the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots($agentId)/Microsoft.Dynamics.CRM.PvaProvision"
    
        try {
            # Make the API call
            Invoke-RestMethod -Method Post -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            Write-Host "Agent Provisioning successfully!" -ForegroundColor Green
            # Add 30 second delay to allow the publish process to complete
            Start-Sleep -Seconds 30
            return $true
        } catch {
            Write-Host "Failed to Provision Agent. Error: $($_.Exception.Message)" -ForegroundColor Red
        }
        return $false
    }
    
    
    # Function to publish a PVA bot
    function Publish-Agent {
        param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$agentId
        )
    
        Write-Host "Publishing agent with ID: $agentId" -ForegroundColor Yellow
    
        # Construct the API endpoint for publishing the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots($agentId)/Microsoft.Dynamics.CRM.PvaPublish"
    
        try {
            # Make the API call
            Invoke-RestMethod -Method Post -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            Write-Host "Agent published successfully!" -ForegroundColor Green
            # Add 30 second delay to allow the publish process to complete
            Start-Sleep -Seconds 30
        } catch {
            Write-Host "Failed to publish Agent. Error: $($_.Exception.Message)" -ForegroundColor Red
        }
    }
    
    function Publish-Agents {
        param (
            [string]$accessToken,
            [array]$agentSchemas
        )
    
        if (-not $agentSchemas -or $agentSchemas.Count -eq 0) {
            Write-Host "No agent schemas provided. Skipping agent publishing." -ForegroundColor Yellow
            return
        }
    
        foreach ($agentSchema in $agentSchemas) {
            #Write-Host "Publishing agent schema: $agentSchema" -ForegroundColor Yellow
    
            try {
                    # Construct the API endpoint for publishing the agent schema
                    $agentId = Get-AgentIdBySchemaName -dataverseUrl $DataverseUrl -accessToken $accessToken -agentSchemaName $agentSchema
    
                    if ($agentId -ne $null) {
                        # check for sync errors
                        if ($CheckBotSyncStatusAndProvisionBots) {
                            $syncStatus = Check-BotSyncErrors -dataverseUrl $DataverseUrl -accessToken $accessToken -botId $agentId
                            if (0 -eq $syncStatus) {
                                Write-Host "Agent has sync errors. Skipping the publish process. Please check the bot: $agentId details" -ForegroundColor Red
                                continue
                            } elseif (2 -eq $syncStatus) {
                                Write-Host "Agent synchronization is still in progress. reprovisioning the agent." -ForegroundColor Yellow
                                if (Provision-Agent -dataverseUrl $DataverseUrl -accessToken $accessToken -agentId $agentId -eq $false) {
                                    Write-Host "Agent reprovisioning failed. Skipping the publish process. Please check the bot: $agentId details" -ForegroundColor Red
                                    continue
                                }
                            } else {
                                Write-Host "Agent synchronization is done. Proceeding to publish." -ForegroundColor Green
                            }
                        }
                        # Step 4: Publish the bot
                        Publish-Agent -dataverseUrl $DataverseUrl -accessToken $accessToken -agentId $agentId
                    } else {
                        Write-Host "Agent not found. Cannot proceed with publishing.Skipping the step" -ForegroundColor Yellow
                    }
            }
            catch {
                Write-Host "An error occurred while publishing agent schema: $agentSchema. Error: $_" -ForegroundColor Red
            }
        }
    
    }
    
    
    # Main script execution
    try {
    
        $expenseAIFlows = $flows
        $agentSchemas = $agents
    
        # Step 1: Interactive login to Azure
        Connect-AzAccount -UseDeviceAuthentication
        $accessToken = Get-AccessToken
        $accessTokenPlainText = Get-AccessTokenPlainText -accessToken $accessToken
    
        # Step 2: Setup ennviornment variables
        update_EnvironmentVariablesForExpense -accessToken $accessTokenPlainText 
        Write-Host "Environment variables updated successfully!" -ForegroundColor Green
    
        # Step 3: Check active connections
        Set-ConnectionReferenceConnection -userProvidedConnectionName $MicrosoftDataverseConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps" -connectionReferenceLogicalName "msdyn_sharedcommondataserviceforapps_2c2d4" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $MicrosoftCopilotStudioConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_microsoftcopilotstudio" -connectionReferenceLogicalName "msdyn_sharedmicrosoftcopilotstudio_26d9d" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $Office365OutlookConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_office365" -connectionReferenceLogicalName "msdyn_sharedoffice365_9b471" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $MicrosoftTeamsConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_teams" -connectionReferenceLogicalName "msdyn_sharedteams_8ea9c" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $Office365UsersConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_office365users" -connectionReferenceLogicalName "msdyn_sharedoffice365users_909b9" -accessToken $accessToken
        
    
        # Step 4: Activate flows
        Activate-Flows -accessToken $accessTokenPlainText -expenseAIFlows $expenseAIFlows
    
        # step 5: publish the agents
        Publish-Agents -accessToken $accessTokenPlainText -agentSchemas $agentSchemas
    
        # Step 6: Publish the solution 
        Publish-Solution -accessToken $accessTokenPlainText
    
        Write-Host "Agent setup completed successfully!" -ForegroundColor Green
    
    } catch {
        Write-Host "An error occurred: $_" -ForegroundColor Red
    }
    
    

    หากต้องการทริกเกอร์ไฟล์ PowerShell ให้ทําตามขั้นตอนเหล่านี้:

    1. เปิด PowerShell (เวอร์ชันขั้นต่ําที่จําเป็น - PowerShell 7)
    2. ไปยังตําแหน่งที่คุณบันทึกไฟล์ (ใช้ตําแหน่งที่ตั้ง <ไฟล์ซีดีคำสั่ง>)
    3. ทริกเกอร์สคริปต์การติดตั้ง (ใช้คําสั่ง '.\Install.ps1')
    4. ทําตามคําแนะนําเพื่อลงชื่อเข้าใช้ Azure
    5. หลังจากที่คุณลงชื่อเข้าใช้ คุณอาจต้องอนุญาตอีกครั้ง (ใช้ ID ผู้ใช้เอเจนต์ที่สร้างขึ้น)

    รอให้สคริปต์ทำงานเสร็จสมบูรณ์ และมองหา การตั้งค่าตัวแทนเสร็จสิ้นเรียบร้อยแล้ว!

    Note

    สคริปต์ก่อนหน้าดําเนินการเหล่านี้:

    • ตั้งค่าตัวแปรสภาพแวดล้อม
    • ตรวจสอบและเชื่อมโยงการอ้างอิงการเชื่อมต่อ
    • เปิดใช้งานโฟลว์ Power Automate
    • เผยแพร่เอเจนต์ Copilot ที่จําเป็น
    • เผยแพร่โซลูชัน Dataverse

    หลังจากเรียกใช้สคริปต์สําเร็จ เอเจนต์ค่าใช้จ่ายจะถูกกําหนดค่าอย่างสมบูรณ์ และพร้อมใช้งาน

    ตัวเลือก B: ตั้งค่าด้วยตนเองใน Power Apps (ไม่มี PowerShell)

    ถ้าคุณไม่ต้องการใช้สคริปต์ PowerShell คุณสามารถกําหนดค่าตัวจัดการค่าใช้จ่ายผ่านทาง Power Apps ได้ด้วยตนเอง กระบวนการนี้เกี่ยวข้องกับการอัปเดตตัวแปรสภาพแวดล้อม การเปิดใช้งานโฟลว์ Power Automate และการเผยแพร่โซลูชัน

    อัปเดตตัวแปรสภาพแวดล้อม

    เมื่อต้องการอัปเดตตัวแปรสภาพแวดล้อม ให้ทําตามขั้นตอนเหล่านี้:

    1. ลงชื่อเข้าใช้ Power Apps และเลือกสภาพแวดล้อมของคุณ

    2. เลือก โซลูชัน จากนั้นเปิด โซลูชันเริ่มต้น (หรือโซลูชันที่ติดตั้งเอเจนต์)

    3. ไปที่ ตัวแปรสภาพแวดล้อม และตั้งค่าต่อไปนี้

      ชื่อตัวแปร คำอธิบาย
      เส้นทางโฟลเดอร์ Outlook ของเอเจนต์ค่าใช้จ่าย ระบุพาธของโฟลเดอร์เพื่อตรวจสอบในกล่องจดหมายที่ใช้ร่วมกัน (ตามค่าเริ่มต้น กล่องขาเข้า)
      รหัสที่อยู่กล่องจดหมายที่ใช้ร่วมกันของเอเจนต์ค่าใช้จ่าย ระบุที่อยู่อีเมลของกล่องจดหมายที่ใช้ร่วมกัน หากต้องการใช้กล่องจดหมายของผู้ใช้ที่ลงชื่อเข้าใช้ ให้ป้อน NA
      URL อินสแตนซ์ของการเงินและการดำเนินงาน ระบุ URL ของสภาพแวดล้อมแอปการเงินและการดำเนินงาน (ตัวอย่างเช่น https://org123.contoso.com)

    เปิดใช้งานโฟลว์ Power Automate

    เอเจนต์ค่าใช้จ่ายต้องอาศัยโฟลว์ Power Automate ต่อไปนี้:

    • การตรวจสอบรายการค่าใช้จ่ายอีกครั้ง
    • การกำหนดค่าค่าใช้จ่าย
    • รับโฟลเดอร์ Outlook ค่าใช้จ่าย
    • สร้างรายงานค่าใช้จ่าย
    • ส่งการ์ดที่ปรับเปลี่ยนได้ของรายงานค่าใช้จ่าย
    • จับคู่ค่าใช้จ่ายโดยอัตโนมัติ
    • ดำเนินการกับอีเมล
    • แยก ID ใบเสร็จที่ไม่ได้แนบไว้สำหรับการเรียกใช้งาน Copilot
    • แยกเอาต์พุตใบเสร็จที่ไม่ได้แนบโดยใช้ปลั๊กอิน Dataverse
    • สร้างรายการค่าใช้จ่าย
    • สร้างรายการค่าใช้จ่ายโดยไม่มี ID โครงการและ ID สถานะ
    • ระบุ ID โครงการ
    • เหตุการณ์ในปฏิทินของผู้ใช้
    • ประมวลผลรายงานค่าใช้จ่ายโดยใช้ Copilot
    • เรียกตัวแทนค่าใช้จ่ายสําหรับการประมวลผลใบเสร็จรับเงิน

    เมื่อต้องการเปิดใช้งานโฟลว์ ให้ทําตามขั้นตอนเหล่านี้:

    1. ลงชื่อเข้าใช้ Power Automate และเลือกสภาพแวดล้อมของคุณ

    2. ให้เลือก โฟลว์ของฉัน

    3. สําหรับแต่ละโฟลว์ 15 รายการในรายการก่อนหน้า ให้ทําตามขั้นตอนเหล่านี้:

      1. ค้นหาโฟลว์
      2. เลือก แก้ไข
      3. สลับไปยังมุมมอง ตัวออกแบบเก่า โดยการปิดตัวเลือก ตัวออกแบบใหม่
      4. รับรองความถูกต้องการเชื่อมต่อที่จําเป็นใดๆ (จนกระทั่งเครื่องหมายถูกสีเขียวปรากฏขึ้น)
      5. เลือก ต่อไป แล้วเลือก บันทึก
      6. เลือก เปิด เพื่อเปิดใช้งานโฟลว์

    เผยแพร่โซลูชัน

    หลังจากที่คุณกําหนดค่าตัวแปรสภาพแวดล้อมและโฟลว์ทั้งหมดเสร็จสิ้นแล้ว ให้ทําตามขั้นตอนเหล่านี้เพื่อเผยแพร่โซลูชัน

    1. ใน Power Apps ไปที่ โซลูชัน
    2. เลือกสภาพแวดล้อมและโซลูชันของคุณ
    3. เลือก เผยแพร่การปรับแต่งทั้งหมด

    เมื่อคุณทําขั้นตอนเหล่านี้เสร็จ ตัวแทนค่าใช้จ่ายจะถูกกําหนดค่าอย่างเต็มที่และพร้อมใช้งาน

    ขั้นตอนที่ 6: เปิดใช้งานเอเจนต์ค่าใช้จ่ายใน Microsoft Teams (ไม่บังคับ)

    เมื่อต้องการเปิดใช้งานการสื่อสารที่ใช้ Teams สําหรับตัวแทนค่าใช้จ่าย ให้เพิ่มแชนเนล Teams ให้กับตัวแทนใน Power Apps จากนั้นตัวแทนสามารถส่งอะแดปทีฟการ์ดผ่าน Teams

    เปิดใช้งานช่องทาง Teams

    หากต้องการเปิดใช้งานแชนเนลของ Teams ให้ทําตามขั้นตอนเหล่านี้:

    1. ลงชื่อเข้าใช้ Copilot Studio และเลือกสภาพแวดล้อมที่ถูกต้อง
    2. บนแท็บ เอเจนต์ เลือก เอเจนต์รายการค่าใช้จ่าย
    3. ในมุมมองเอเจนต์ บนแท็บ ช่องทาง ให้เลือก Teams และ Microsoft 365 Copilot
    4. เลือก เพิ่มช่องทาง เพื่อเปิดใช้งานการรวม Teams และทําตามขั้นตอนในส่วน กําหนดค่าความพร้อมใช้งานของแอป Teams เพื่อกําหนดค่าผู้ที่คุณต้องการแชร์แอปด้วย

    เรียนรู้เพิ่มเติมใน เปิดแผงการกําหนดค่าสําหรับช่องทาง Teams + Microsoft 365

    กําหนดค่าความพร้อมใช้งานของแอป Teams

    เมื่อต้องการกําหนดค่าความพร้อมใช้งานของแอป Teams ให้ทําตามขั้นตอนเหล่านี้:

    1. หลังจากสร้างแอป Teams แล้ว ให้เลือก ตัวเลือกความพร้อมใช้งาน

    2. เลือกผู้ที่คุณต้องการแชร์ด้วย:

      • ผู้ใช้ที่เฉพาะเจาะจงภายในองค์กร
      • ทั้งองค์กร
    3. ส่งแอปเพื่อขออนุมัติ

    เผยแพร่แอปในศูนย์การจัดการ Teams

    หากต้องการเผยแพร่แอปในศูนย์การจัดการ Teams ให้ทําตามขั้นตอนเหล่านี้:

    1. เข้าสู่ระบบ ศูนย์การจัดการ Teams
    2. ไปที่ แอป Teams > จัดการแอป ค้นหา "ค่าใช้จ่าย" และเลือกแอป ตัวแทนรายการค่าใช้จ่าย ที่สถานะแอปถูกบล็อก
    3. เลือก เผยแพร่ เพื่อยกเลิกการบล็อกแอป เมื่อการดําเนินการเผยแพร่เสร็จสมบูรณ์ ตรวจสอบให้แน่ใจว่าสถานะแอปเปลี่ยนเป็นไม่ได้บล็อก

    เรียนรู้เพิ่มเติมใน เชื่อมต่อและกำหนดค่าเอเจนต์สำหรับ Teams และ Microsoft 365

    เมื่อคุณทําตามขั้นตอนเหล่านี้ ตัวแทนค่าใช้จ่าย ของคุณพร้อมใช้งานแล้ว

    Note

    คุณยังสามารถให้คําติชมเกี่ยวกับรายการและรายงานค่าใช้จ่ายที่สร้างโดยตัวแทนโดยใช้ไอคอนยกนิ้วโป้งขึ้นและคว่ํานิ้วโป้งลง และป๊อปอัปคําติชมภายในสภาพแวดล้อมการเงินของ Dynamics 365

    ถอนการติดตั้งเอเจนต์ค่าใช้จ่าย

    เมื่อต้องการ ถอนการติดตั้ง เจ้าหน้าที่ค่าใช้จ่าย ให้ทําตามขั้นตอนเหล่านี้:

    1. ลงชื่อเข้าใช้พอร์ทัลผู้สร้าง Microsoft Power Apps
    2. เลือก โซลูชัน ค้นหา msdyn_ExpenseAI เลือกจุดสามจุด แล้วเลือก ลบ
    3. ค้นหา msdyn_FnOCopilotAnchor และลบโซลูชัน