Project Management
8 TopicsFrom Overwhelmed to Organized: How Subtasks Transform Project Management
Do you often find yourself lost in a maze of tasks within your projects? Are checklists not enough for you to keep your projects organized? With the new Microsoft Planner, you can bring order to chaos with subtasks, enabling you to manage complex plans and projects with ease.27KViews3likes20CommentsBuilding a Gantt Chart using Power BI
Few weeks ago, I was tasked to build a Gantt chart, but I didn’t have a clue on how to do it. So, I did it the “Old fashion way” using excel sheet and adding all the adjustments manually i.e., colors, timeline, dates and tasks. I completed the task, but I felt there was a way around it and that was when I discovered a visualization on Power BI where you can build a Gantt chart is just a matter of minutes. Let’s breakdown the step-by-step process to achieve this. Don’t worry if this is new to you🙂. Let’s get to the introduction.154KViews1like10CommentsGenAI based Project Management
Phase 1 We wanted to develop a Gen AI solution for Project Management activities like below. Can anyone guide us or help how we can start? We are in the learning phase of Gen AI with MS learn materials & video courses. Effort estimation based on task description and technology Creating tasks/subtasks/comments in the ERP project module Assign the developer/resources based on the skill required Monitor the progress of projects & tasks Taking follow-up with the developer for particular tasks through task updates, Teams chat & Teams call. Create a project progress report and share it with the respective customer through email. Make the Teams call with the developer and discuss the progress/challenges (One to one call & group call) Attend customer meeting calls, prepare meeting notes and share them with all the participants. Make the phone call (VOIP) to employees/developers/customers/contractors for the project/task update. Attending customer calls/ Team calls to understand the requirements and create a project scope document.3KViews0likes8CommentsAzure DevOps - Send an email to each Project Administrator with Account listed into using PowerShell
We saw with a previous script how have a consolidated view of DevOps usage per organization: Azure DevOps - How to collect all accounts from Organization using PowerShell That solution associated with Power Bi report is giving a good overall view of your IT delivery team and licenses. But because the project management and user permission is under Project Manager umbrella, this new script is looking per organization and per project to send an email to Azure DevOps Project managers listing all accounts (with group, licenses, last connection, etc.) existing into their project. Based on that script, you can better review permission and license management accorded with project owners, and match with real needs. This is also a security basic reviewing the external access (Partner, Suppliers, Customers, etc.). Import-module AzureAD connect-azureAD #region -- Customized Script Settings (need to be reviewed) --- # ================== / Parameters to Adapt \ ================== [string]$GlobalPATForAllORganizations= "yyxxxxyyyyyxxxxxyyyy" [string]$JSonFolderPath = "C:\DEVOPS_PROJECTS" [string]$DomainNameEmail = "@yourdomain.com" # -- Email configuration ---- [string]$DevOpsAdmins = "AdminEmail@yourdomain.com" [string]$SMTPServer = "your.smtp.yourdomain.com" [string]$EmailCoreTitle = "[[yourproject]] - Review Azure DevOps Accounts and licenses associated" [string]$EmailPreCoreContent = "<DIV><P>Dear team,<BR><BR> We are reviewing all Azure DevOps accounts associated with your project <B>[[yourproject]]</B>.<BR> You can find an extract of all accounts listed for your project, and we need your control on each of those.<BR><BR> Please to check each account and confirm if we have to:<BR> <UL> <LI>Remove the account from your project</LI> <LI>Downgrade the license level, from Basic or Visual Studio (license paid) to Stakeholder (free of charge restricted to Work Items) - <a href='https://docs.microsoft.com/en-us/azure/devops/organizations/security/access-levels?view=azure-devops#supported-access-levels'>More details</a></LI> </UL> <BR> Send that reviewed list to this email address '<B>$($DevOpsAdmins)</B>' and the change will be applied.<BR><BR> ---- ACCOUNT INTO YOUR DEVOPS PROJECT: [[yourproject]] ------</P></DIV>" [string]$EmailPostCoreContent = "<DIV><P>-------------------------------------------------------------<BR><BR> Thanks for your help.<BR> Best Regards<BR><BR> DevOps Administrator</P></DIV>" # ================== \ Parameters to Adapt / ================== #endregion #region -- Internal Script Settings --- $OrganizationList = @() $ProjectAdministrators = @() [string]$PAT = "" [string]$OrganizationName = "" [string]$Organization = "" [string]$SecurityGroupsJSonFilePath = "" [string]$UserGroupJSonFilePath = "" [string]$GroupsListJSonFilePath = "" [string]$AccountValidInAzureAD = "" $DataRefreshDate = Get-Date -Format "yyyy-MM-dd" [int]$TotalProjectPerOrganization = 0 [int]$ProjectInProgress = 0 # -- Email configuration ---- [string]$TempEmailAddress = "" [string]$ProjectOwnerEmailAddresses = "" [string]$ListToPutInMail = "" [string]$EmailCoreTitleToUse = "" [string]$EmailPreCoreContentToUse = "" [string]$HTMLHeader = @" <style> TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;} TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #FF6600;} TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;} </style> "@ #endregion #region -- Each Az DevOps Organization -- #YourOrganization1 $PAT = $GlobalPATForAllORganizations #https://dev.azure.com/YourOrganization1/_usersSettings/tokens $OrganizationName = "YourOrganization1" $OrganizationWithPAT = New-Object PSObject -property @{OrganizationName=$OrganizationName;OrganizationPAT=$PAT} $OrganizationList += $OrganizationWithPAT #YourOrganization2 $PAT = $GlobalPATForAllORganizations #https://dev.azure.com/YourOrganization2/_usersSettings/tokens $OrganizationName = "YourOrganization2" $OrganizationWithPAT = New-Object PSObject -property @{OrganizationName=$OrganizationName;OrganizationPAT=$PAT} $OrganizationList += $OrganizationWithPAT #YourOrganization3 $PAT = $GlobalPATForAllORganizations #https://dev.azure.com/YourOrganization3/_usersSettings/tokens $OrganizationName = "YourOrganization3" $OrganizationWithPAT = New-Object PSObject -property @{OrganizationName=$OrganizationName;OrganizationPAT=$PAT} $OrganizationList += $OrganizationWithPAT #endregion foreach($MyOrganization in $OrganizationList) { write-host " --------------------------------------------------------------------" -ForegroundColor White -BackgroundColor DarkYellow write-host " ----- Organization :", $MyOrganization.OrganizationName ," ------" -ForegroundColor White -BackgroundColor DarkYellow write-host " --------------------------------------------------------------------" -ForegroundColor White -BackgroundColor DarkYellow $TotalProjectPerOrganization = 0 $ProjectInProgress = 0 $Organization = "https://dev.azure.com/$($MyOrganization.OrganizationName)/" $UserGroupJSonFilePath = "$JSonFolderPath\$($MyOrganization.OrganizationName)-UserGroups.json" $GroupsListJSonFilePath = "$JSonFolderPath\$($MyOrganization.OrganizationName)-AllProjects-List.json" $SecurityGroupsJSonFilePath = "$JSonFolderPath\$($MyOrganization.OrganizationName)-SecurityGroups-List.json" echo $($MyOrganization.OrganizationPAT) | az devops login --org $Organization az devops configure --defaults organization=$Organization #$allProjects = az devops project list --org $Organization --top 1 | ConvertFrom-Json | Select-Object -ExpandProperty value | Sort-Object name #Select 1st project to validate script #$allProjects = az devops project list --org $Organization --top 10000 | ConvertFrom-Json | Select-Object -ExpandProperty value | Where-Object name -eq "YourProjectname" | Sort-Object name #Select filtered project $allProjects = az devops project list --org $Organization --top 10000 | ConvertFrom-Json | Select-Object -ExpandProperty value | Sort-Object name #Select all projects #$allProjects #$allProjects | ConvertTo-Json | Out-File -FilePath $GroupsListJSonFilePath -Encoding UTF8 #If you want to save a copy $TotalProjectPerOrganization = $allProjects.Count foreach($myProject in $allProjects) { $ProjectInProgress += 1 $ProjectAdministrators = @() $EmailPreCoreContentToUse = "" $EmailCoreTitleToUse = "" $ProjectOwnerEmailAddresses = "" $ListToPutInMail = "" $UserGroupsPerOrganizationAndProject = @() write-host " ---------------------------------------------------------------------------------------------------- " -ForegroundColor Yellow write-host " -- Project Name:", $myProject.Name, "[", $ProjectInProgress, " of ", $TotalProjectPerOrganization, "] --" -ForegroundColor Yellow #write-host " > Project Description:", $myProject.Description -ForegroundColor DarkYellow write-host " ---------------------------------------------------------------------------------------------------- " -ForegroundColor Yellow $ProjectSecurityGroups = az devops security group list --org $Organization --project $myProject.Name | ConvertFrom-Json #$ProjectSecurityGroups | Out-File -FilePath $SecurityGroupsJSonFilePath #-Encoding UTF8 #If you want to save a copy foreach($mySecurityGroup in $ProjectSecurityGroups.graphGroups) { write-host " - Security Group Name:", $mySecurityGroup.displayName, "- Descriptor:", $mySecurityGroup.descriptor -ForegroundColor Magenta #write-host " > Security Group Description:", $mySecurityGroup.Description -ForegroundColor DarkMagenta $AllGroupMembers = az devops security group membership list --id $mySecurityGroup.descriptor --org $Organization --relationship members | ConvertFrom-Json #write-host " JSON:", $AllGroupMembers #$AllGroupMembers | ConvertTo-Json | Out-File -FilePath $UserGroupJSonFilePath -Encoding UTF8 #If you want to save a copy [array]$groupMembers = ($AllGroupMembers | Get-Member -MemberType NoteProperty).Name foreach($MyUserInGroup in $groupMembers) { if($AllGroupMembers.$MyUserInGroup.mailAddress -ne $null) { $AccountValidInAzureAD = "" write-host " ==> User Name:", $AllGroupMembers.$MyUserInGroup.displayName, "- Email:", $AllGroupMembers.$MyUserInGroup.mailAddress -ForegroundColor Green if($AllGroupMembers.$MyUserInGroup.mailAddress.endswith($DomainNameEmail)) { $TempEmailAddress = $AllGroupMembers.$MyUserInGroup.mailAddress -replace "'", "''" $MyAzureADUser = Get-AzureADUser -Filter "userPrincipalName eq '$($TempEmailAddress)'" if($MyAzureADUser) { if($MyAzureADUser.AccountEnabled) { $AccountValidInAzureAD = "ACCOUNT VALID IN AZURE ACTIVE DIRECTORY" } else { $AccountValidInAzureAD = "ACCOUNT DISABLE IN AZURE ACTIVE DIRECTORY" } } else { $AccountValidInAzureAD = "ACCOUNT NOT EXIST IN AZURE ACTIVE DIRECTORY" } } else { $AccountValidInAzureAD = "ACCOUNT NOT INTERNAL EMAIL ADDRESS" } $MyUserDetails = az devops user show --user $AllGroupMembers.$MyUserInGroup.mailAddress --org $Organization | ConvertFrom-Json #write-host " JSON:", $MyUserDetails $UserGroupsPerOrganizationAndProject += New-Object -TypeName PSObject -Property @{ UserName=$AllGroupMembers.$MyUserInGroup.displayName mailAddress=$AllGroupMembers.$MyUserInGroup.mailAddress AccountStatusInAzureAD = $AccountValidInAzureAD LicenseType=$MyUserDetails.accessLevel.licenseDisplayName dateCreated=$($MyUserDetails.dateCreated).Substring(0, 10) lastAccessedDate=$($MyUserDetails.lastAccessedDate).Substring(0, 10) ProjectName= $myProject.Name GroupName=$mySecurityGroup.displayName DataRefreshDate = $DataRefreshDate } } } } $EmailCoreTitleToUse = $EmailCoreTitle.replace("[[yourproject]]", $myProject.Name) $ProjectAdministrators = $UserGroupsPerOrganizationAndProject | where { $_.GroupName -eq "Project Administrators" } | Select mailAddress if($ProjectAdministrators.count -gt 0) { foreach ($myProjectAdminEMail in $ProjectAdministrators) { if ($myProjectAdminEMail.mailAddress.endswith($DomainNameEmail)) { $ProjectOwnerEmailAddresses += $myProjectAdminEMail.MailAddress $ProjectOwnerEmailAddresses += ";" } } if($ProjectOwnerEmailAddresses -eq "") { $ProjectOwnerEmailAddresses = $DevOpsAdmins $EmailCoreTitleToUse = "NO INTERNAL PROJECT ADMIN - " + $EmailCoreTitleToUse } } else { $ProjectOwnerEmailAddresses = $DevOpsAdmins $EmailCoreTitleToUse = "NO PROJECT ADMIN - " + $EmailCoreTitleToUse } $UserGroupsPerOrganizationAndProject | ConvertTo-Json #write-host " JSON:", $UserGroupsPerOrganizationAndProject $EmailPreCoreContentToUse = $EmailPreCoreContent.replace("[[yourproject]]", $myProject.Name) #$ListToPutInMail = $UserGroupsPerOrganizationAndProject | Format-Table UserName, mailAddress, AccountStatusInAzureAD, LicenseType, GroupName, dateCreated, lastAccessedDate | Out-String $ListToPutInMail = $UserGroupsPerOrganizationAndProject | ConvertTo-Html -Property UserName, mailAddress, AccountStatusInAzureAD, LicenseType, GroupName, dateCreated, lastAccessedDate -PreContent $EmailPreCoreContentToUse -PostContent $EmailPostCoreContent -Head $HTMLHeader | Out-String #write-host " HTML Table:", $ListToPutInMail #write-host " Project Admins:", $ProjectAdministrators $ProjectOwnerEmailAddresses = $ProjectOwnerEmailAddresses.Trim() if($ProjectOwnerEmailAddresses.EndsWith(";")) { write-host " Remove last char from:", $ProjectOwnerEmailAddresses $ProjectOwnerEmailAddresses = $ProjectOwnerEmailAddresses.Substring(0, $ProjectOwnerEmailAddresses.Length-1) write-host " Last char removed from:", $ProjectOwnerEmailAddresses } write-host " Project Admin Emails:", $ProjectOwnerEmailAddresses write-host " *> Email Title:", $EmailCoreTitleToUse Send-MailMessage -To $ProjectOwnerEmailAddresses.split(';') -From $DevOpsAdmins -Cc $DevOpsAdmins -Subject $EmailCoreTitleToUse -Body $ListToPutInMail -BodyAsHtml -SmtpServer $SMTPServer write-host " ---------------------------------------------------------------------------------------------------- " -ForegroundColor Yellow } write-host " --------------------------------------------------------------------" -ForegroundColor White -BackgroundColor DarkYellow } You have a restricted list of settings to adapt and run the script. In any case, that part need to be integrated into your FinOps process to optimize your license costs as you really need and use. Fabrice Romelard References used to build that script: https://docs.microsoft.com/en-us/cli/azure/ext/azure-devops/devops/project?view=azure-cli-latest https://www.colinsalmcorner.com/az-devops-like-a-boss/ https://tenbulls.co.uk/2020/01/06/using-azure-cli-to-query-azure-devops/4.1KViews0likes0CommentsAzure DevOps for Beginners: How to Set Up Your Account, Organization, and Repository
Microsoft Learn Student Ambassador and developer in Power Platform and Dynamics 365 Customer Engagement, Rachel Irabor, shares how to create a new organization and repository in Azure DevOps. This step-by-step guide will walk you through the process of setting up an Azure DevOps account and creating a new organization, project, and repository. Follow this guide and start building your own projects in Azure DevOps.12KViews4likes2CommentsProject Activity Inquisition
Hello there, I am in my final year(university) and I major in Project Management, but, I have not really had a project manager's experience neither do I have project managers at my reach to ask questions and this bothers me a lot. I have taken a step in learning MS Project, and I am enjoying it. I want to know, in the process of scheduling for a project, as a new project manager, how will I know the activities to be listed and their respective duration? Will I have to go to each department to request this? I will appreciate a detailed answer. Thanks:)1.2KViews0likes5CommentsHow to deal with Teams when the corresponding project is done?
We want to utilize Teams as our new project management tool in our organisation. The idea is to create a new team for every project that comes up and use it not only for communications but also for file management and tasks. Our question is now: what should we do when a project is done? AFAIK there is no way to "close" the Team, only to delete it. But if we delete it, all files, communications etc. will be deleted as well and we cannot do this because we might want to look inside it later. But if we dont delete, everyone who was involved will have this team entry visible in Teams forever and eventually there will be tons of entries.. What is best practice here? Thanks!Solved1.7KViews0likes2CommentsSample Project Plan for upgrade from SharePoint 2013 to 2019
Are there sample project plans for upgrading SharePoint to 2019, in particular SharePoint 2013 to SharePoint 2019? If not, and if I create one, where would be a good place to store it? SharePoint PnP or some other place? https://github.com/SharePoint/PnP1.7KViews0likes1Comment