├── .gitignore ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── build.ps1 ├── build ├── .psdeploy.ps1 ├── ScriptAnalyzerSettings.psd1 ├── requirements.psd1 └── tasks.build.ps1 ├── media ├── MicrosoftMVPLogo.png ├── New-MVPContribution01.jpg ├── New-MVPContribution02.jpg ├── New-MVPContribution03.jpg ├── New-MVPContribution04.jpg ├── Set-MVPConfiguration01.jpg ├── Set-MVPConfiguration02.jpg └── Set-MVPConfiguration03.jpg ├── src ├── private │ ├── Get-MVPOAuthAutorizationCode.ps1 │ └── Show-MVPOAuthWindow.ps1 ├── public │ ├── Get-MVPConsiderationAnswer.ps1 │ ├── Get-MVPConsiderationQuestion.ps1 │ ├── Get-MVPContribution.ps1 │ ├── Get-MVPContributionArea.ps1 │ ├── Get-MVPContributionType.ps1 │ ├── Get-MVPContributionVisibility.ps1 │ ├── Get-MVPOnlineIdentity.ps1 │ ├── Get-MVPProfile.ps1 │ ├── Get-MVPProfileImage.ps1 │ ├── Lock-MVPConsiderationAnswer.ps1 │ ├── New-MVPConsiderationAnswer.ps1 │ ├── New-MVPContribution.ps1 │ ├── New-MVPOnlineIdentity.ps1 │ ├── Remove-MVPConfiguration.ps1 │ ├── Remove-MVPContribution.ps1 │ ├── Remove-MVPOnlineIdentity.ps1 │ ├── Set-MVPConfiguration.ps1 │ ├── Set-MVPContribution.ps1 │ ├── Set-MVPOnlineIdentity.ps1 │ ├── Show-MVPProfile.ps1 │ └── Test-MVPContribution.ps1 ├── source.psd1 └── source.psm1 └── tests └── module.tests.ps1 /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore folder output 2 | output/ 3 | buildoutput/ 4 | dependencies/ 5 | archive/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "powershell.codeFormatting.openBraceOnSameLine": false, 3 | "powershell.codeFormatting.newLineAfterOpenBrace": true, 4 | "powershell.codeFormatting.preset": "Allman", 5 | "editor.renderWhitespace": "all", 6 | "editor.tabSize": 4, 7 | "editor.detectIndentation": false, 8 | "files.defaultLanguage": "powershell", 9 | "[json]": { 10 | "editor.tabSize": 2 11 | }, 12 | "files.trimTrailingWhitespace": true 13 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Thanks for considering contributing to this project! My name is Francois-Xavier Cat ([@lazywinadmin](https://github.com/lazywinadmin)), and I'm excited you're interested in improving something I've written. 4 | 5 | I'm happy to consider any contributions, especially ones that add functionality or fix bugs. 6 | 7 | ## Ground Rules 8 | 9 | I really only have one rule for contributions: 10 | 11 | > This project is licensed under The MIT License, so your contribution will need to use the same license in order to be accepted. 12 | 13 | If I accept your contribution, I'll add you to the Authors/Contributors section in the README. 14 | 15 | ## How to Contribute 16 | 17 | If you would like to make a simple contribution (a few lines or less), please put it in an Issue with the "contribution" label. 18 | 19 | For larger contributions, please fork this project, make the changes/additions, and then issue a Pull Request. 20 | Never done a pull request before? There's an easy tutorial [here](http://makeapullrequest.com/). 21 | 22 | ## How to report a bug 23 | 24 | ### Vulnerabilities 25 | 26 | If you find a security vulnerability, please do NOT open an Issue. Instead, email info@REPLACE-THIS-WITH-MY-GITHUB-USERNAME.com 27 | 28 | ### Non-Security Bugs 29 | 30 | For non-security bugs, please open a GitHub issue with the "bug" label containing the following information: 31 | 32 | > 1. What OS and PowerShell version are you using? 33 | > 2. What did you do? 34 | > 3. What did you expect to see? 35 | > 4. What did you see instead? 36 | 37 | ## How to suggest a feature or enhancement 38 | 39 | If you wish to suggest a feature or enhancement, please enter a GitHub issue with the "enhancement" label detailing the suggestion. 40 | 41 | ## Code review process 42 | 43 | As I'm just one person, and my scripting is a side-project to my normal sysadmin/syseng work, it may take me a while to review. 44 | 45 | ## Questions 46 | 47 | If you have additional questions about contributing, please open a GitHub issue with the "question" tag. 48 | 49 | ## Code Style 50 | 51 | I write all my PowerShell code according to the [PowerShell Best Practices and Style Guide](https://github.com/PoshCode/PowerShellPracticeAndStyle), so any contributions will be altered to match this style if they do not already follow it. 52 | 53 | ## Notes 54 | 55 | This page was created based mostly on [Nate Contributing page](https://github.com/natescherer/ChangelogManagement/blob/master/CONTRIBUTING.md). Thank you ! -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 PowerShellLab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MVP PowerShell Module 2 | 3 | > ⚠️ **__IMPORTANT__** 4 | > **This module will stop working on the 29th of April 2022.** 5 | > 6 | > Unfortunately Microsoft decided to retire the Microsoft MVP API. 7 | > :disappointed: :disappointed: :disappointed: 8 | > 9 | > *We would like to inform you that as of April 29th, 2022, the MVP Portal API will be decommissioned due to technical support limitations and incompatibility with Microsoft 10 | accessibility guidelines. If you would like to add contributions to your profile, you can access the 11 | [MVP Private page](https://mvp.microsoft.com/) and 12 | perform this task directly.* 13 | 14 | ![](media/MicrosoftMVPLogo.png) 15 | 16 | [![Build Status](https://dev.azure.com/lazywinadmin/MVP/_apis/build/status/lazywinadmin.MVP?branchName=master)](https://dev.azure.com/lazywinadmin/MVP/_build/latest?definitionId=18&branchName=master) 17 | 18 | PowerShell Module to interact with the Microsoft MVP API and manage your contributions (Get, Add, Update and Remove), retrieve contributions type and technologies, retrieve a mvp profile and maintain your online identities. 19 | 20 | **Youtube video**: [Using the PowerShell MVP Module](https://www.youtube.com/watch?v=UeRvlMzfsT8) 21 | 22 | ## Table of Contents 23 | * [Getting Started](#Usage) 24 | * [Configure connection](#Configure) 25 | * [Requirements](#requirements) 26 | * [Commands](#commands) 27 | * [Get-MVPProfile](#GetMVPProfile) 28 | * [Get-MVPContributionType](#GetMVPContributionType) 29 | * [Get-MVPContributionArea](#GetMVPContributionArea) 30 | * [Get-MVPContribution](#GetMvpContribution) 31 | * [New-MVPContribution](#NewMvpContribution) 32 | * [New-MVPContribution (multiple)](#NewMvpContributionMultiple) 33 | * [Remove-MVPContribution](#RemoveMvpContribution) 34 | * [Remove-MVPContribution (Multiple)](#RemoveMvpContributionMultiple) 35 | * [Show-MVPProfile](#ShowMvpProfile) 36 | * [Authentication](#Authentication) 37 | * [Persistent SubscriptionKey](#PersistentSubscriptionKey) 38 | * [Clear Authenticaton](#Clearauthentication) 39 | * [ToDo](#Todo) 40 | * [Contributing](#Contributing) 41 | * [More Information](#MoreInformation) 42 | 43 | 44 | 45 | ## Getting Started 46 | 47 | ```powershell 48 | # Install the Module from the PowerShell Gallery 49 | Install-module -Name MVP -Scope CurrentUser -Repository PSGallery 50 | ``` 51 | 52 | 53 | 54 | ### Configure Connection 55 | 56 | In order to use this module you need to get a Subscription Key from [https://mvpapi.portal.azure-api.net/](https://mvpapi.portal.azure-api.net/), [see the steps below](#Configure) or follow the documentation from Microsoft: 57 | 58 | * [Getting Started with Microsoft MVP API](https://mvp.microsoft.com/en-us/Opportunities/my-opportunities-api-getting-started) 59 | * [Microsoft Video Tutorial](https://aka.ms/mvp-api-video) 60 | * [Microsoft MVP API](https://mvpapi.portal.azure-api.net/) 61 | 62 | Fortunalely the step above just need to be done once. 63 | 64 | Once you have access, follow the following steps to retrieve the Subscription Key. 65 | 66 | 1. Go to the [Microsoft MVP API Developer Portal](https://mvpapi.portal.azure-api.net/) 67 | 2. Click the ```Sign In``` button and sign in with your Microsoft Account. It must be the same Microsoft Account as you use for your Microsoft MVP Site access. 68 | 3. Subscribe to the ```MVP Production``` product. 69 | 4. Go to the ```PRODUCTS``` tab, and choose ```MVP Production```. 70 | 5. Click the ```Subscribe``` button. 71 | 6. This request will be reviewed and Accepted / Declined by the admin in one or two business days. The admin verifies your access permission based on your Microsoft Account. It must be the same Microsoft Account as you use for your Microsoft MVP Site access. 72 | 7. Once approved, on the top right corner click on your name and select ```PROFILE``` 73 | 8. You should see a subscription for the ```MVP Production``` 74 | 9. On the ```Primary Key``` line, select ```Show``` and this is your Subscription Key 75 | 10. You are ready to use the module, see below 76 | 77 | 78 | ```powershell 79 | # Set your connection to the MVP API 80 | $SubscriptionKey = 'abcdef083b5b482f8d99184d318b12f6' # this is a fake key btw ;) 81 | Set-MVPConfiguration -SubscriptionKey $SubscriptionKey 82 | ``` 83 | 84 | A user interface will show to authenticate against the Microsoft API "mvpapi.portal.azure-api.net" 85 | 86 | ![Alt text](media/Set-MVPConfiguration01.jpg?raw=true "Set-MVPConfiguration") 87 | 88 | ![Alt text](media/Set-MVPConfiguration02.jpg?raw=true "Set-MVPConfiguration") 89 | 90 | ![Alt text](media/Set-MVPConfiguration03.jpg?raw=true "Set-MVPConfiguration") 91 | 92 | 93 | 94 | ### Commands 95 | 96 | ```powershell 97 | # Retrieve all the commands 98 | Get-Command -module MVP 99 | ``` 100 | 101 | Output: 102 | ``` 103 | CommandType Name Version Source 104 | ----------- ---- ------- ------ 105 | Function Get-MVPContribution 0.0.3 MVP 106 | Function Get-MVPContributionArea 0.0.3 MVP 107 | Function Get-MVPContributionType 0.0.3 MVP 108 | Function Get-MVPContributionVisibility 0.0.3 MVP 109 | Function Get-MVPOnlineIdentity 0.0.3 MVP 110 | Function Get-MVPProfile 0.0.3 MVP 111 | Function Get-MVPProfileImage 0.0.3 MVP 112 | Function New-MVPContribution 0.0.3 MVP 113 | Function New-MVPOnlineIdentity 0.0.3 MVP 114 | Function Remove-MVPConfiguration 0.0.3 MVP 115 | Function Remove-MVPContribution 0.0.3 MVP 116 | Function Remove-MVPOnlineIdentity 0.0.3 MVP 117 | Function Set-MVPConfiguration 0.0.3 MVP 118 | Function Set-MVPContribution 0.0.3 MVP 119 | Function Set-MVPOnlineIdentity 0.0.3 MVP 120 | Function Show-MVPProfile 0.0.3 MVP 121 | Function Test-MVPContribution 0.0.3 MVP 122 | ``` 123 | 124 | 125 | 126 | ### Retrieve a MVP Profile 127 | 128 | 129 | ```powershell 130 | # Retrieve your own profile 131 | Get-MVPProfile 132 | 133 | # Retrieve a specific profile 134 | Get-MVPProfile -ID 5000475 135 | ``` 136 | 137 | ``` 138 | Metadata : @{PageTitle=Francois-Xavier Cat is a Microsoft MVP in PowerShell who has been in the IT field since 2007. He is currently an 139 | Automation Specialist in a large Financial company.; TemplateName=; Keywords=; Description=} 140 | MvpId : 5000475 141 | YearsAsMvp : 4 142 | FirstAwardYear : 2014 143 | AwardCategoryDisplay : Cloud and Datacenter Management 144 | TechnicalExpertise : 145 | InTheSpotlight : False 146 | Headline : Francois-Xavier Cat is a Microsoft MVP in PowerShell who has been in the IT field since 2007. He is currently an Automation 147 | Specialist in a large Financial company. 148 | Biography : Francois-Xavier Cat is from France but has been living in Montreal, Quebec, Canada since 2004. 149 | 150 | In 2014, He was concurrently awarded his first MVP PowerShell by Microsoft and PowerShell Hero 2014 award by PowerShell.org. 151 | In 2015, he was also nominated Sapien Technologies MVP. 152 | 153 | You can follow his blog at http://lazywinadmin.com 154 | DisplayName : Francois-Xavier Cat 155 | FullName : Francois-Xavier Cat 156 | PrimaryEmailAddress : 157 | ShippingCountry : Canada 158 | ShippingStateCity : Montreal, QC 159 | Languages : French, English 160 | OnlineIdentities : {@{PrivateSiteId=39435; SocialNetwork=; Url=https://www.facebook.com/fxavierc; OnlineIdentityVisibility=; 161 | ContributionCollected=False; DisplayName=; UserId=; MicrosoftAccount=; PrivacyConsentStatus=False; 162 | PrivacyConsentCheckStatus=False; PrivacyConsentCheckDate=; PrivacyConsentUnCheckDate=; Submitted=False}, 163 | @{PrivateSiteId=74012; SocialNetwork=; Url=https://www.facebook.com/lazywinadmin; OnlineIdentityVisibility=; 164 | ContributionCollected=False; DisplayName=; UserId=; MicrosoftAccount=; PrivacyConsentStatus=True; 165 | PrivacyConsentCheckStatus=False; PrivacyConsentCheckDate=; PrivacyConsentUnCheckDate=; Submitted=False}, 166 | @{PrivateSiteId=56689; SocialNetwork=; Url=http://klout.com/LazyWinAdm; OnlineIdentityVisibility=; 167 | ContributionCollected=False; DisplayName=; UserId=; MicrosoftAccount=; PrivacyConsentStatus=False; 168 | PrivacyConsentCheckStatus=False; PrivacyConsentCheckDate=; PrivacyConsentUnCheckDate=; Submitted=False}, 169 | @{PrivateSiteId=39415; SocialNetwork=; Url=http://ca.linkedin.com/in/fxcat; OnlineIdentityVisibility=; 170 | ContributionCollected=False; DisplayName=; UserId=; MicrosoftAccount=; PrivacyConsentStatus=True; 171 | PrivacyConsentCheckStatus=False; PrivacyConsentCheckDate=; PrivacyConsentUnCheckDate=; Submitted=False}...} 172 | Certifications : {@{PrivateSiteId=9874; Id=a2136352-509a-e411-bbc8-6c3be5a82b68; Title=VMware VCP510-DCV,; CertificationVisibility=}} 173 | Activities : 174 | CommunityAwards : {@{PrivateSiteId=12499; Title=SAPIEN MVP; Description="SAPIEN Most Valuable Professional (MVP) award. It’s our way to 175 | recognize and show 176 | our appreciation for community members who promote our products and contribute 177 | to their improvement and success."; DateEarned=2015-01-16T00:00:00; 178 | ReferenceUrl=http://www.sapien.com/company/mvp/13/Francois-Xavier_Cat; AwardRecognitionVisibility=}, @{PrivateSiteId=6179; 179 | Title=PowerShell Hero; Description=; DateEarned=2014-01-08T00:00:00; 180 | ReferenceUrl=http://powershell.org/wp/2014/01/08/announcing-our-2014-powershell-heroes/; AwardRecognitionVisibility=}} 181 | NewsHighlights : {} 182 | UpcomingEvent : {} 183 | ``` 184 | 185 | 186 | 187 | 188 | ### Retrieve Contribution Type 189 | ```powershell 190 | Get-MVPContributionType | Select-Object -ExpandProperty Name 191 | ``` 192 | ``` 193 | Article 194 | Blog Site Posts 195 | Book (Author) 196 | Book (Co-Author) 197 | Code Project/Tools 198 | Code Samples 199 | Conference (booth presenter) 200 | Conference (organizer) 201 | Forum Moderator 202 | Forum Participation (3rd Party forums) 203 | Forum Participation (Microsoft Forums) 204 | Mentorship 205 | Open Source Project(s) 206 | Other 207 | Product Group Feedback 208 | Site Owner 209 | Speaking (Conference) 210 | Speaking (Local) 211 | Speaking (User group) 212 | Technical Social Media (Twitter, Facebook, LinkedIn...) 213 | Translation Review, Feedback and Editing 214 | User Group Owner 215 | Video 216 | Webcast 217 | WebSite Posts 218 | ``` 219 | 220 | 221 | 222 | 223 | ### Retrieve Contribution Area 224 | ```powershell 225 | # Retrieve current Area 226 | Get-MVPContributionArea 227 | ``` 228 | 229 | ``` 230 | AwardName ContributionArea 231 | --------- ---------------- 232 | Cloud and Datacenter Management {@{Id=b003f4ef-066b-e511-810b-fc15b428ced0; Name=Azure Stack; AwardName=Cloud and Datacenter Management; AwardCate... 233 | ``` 234 | 235 | ```powershell 236 | # Retrieve current Area items 237 | Get-MVPContributionArea | Select-Object -ExpandProperty ContributionArea 238 | ``` 239 | 240 | 241 |
242 | Output 243 | 244 | ``` 245 | Id : b003f4ef-066b-e511-810b-fc15b428ced0 246 | Name : Azure Stack 247 | AwardName : Cloud and Datacenter Management 248 | AwardCategory : My Awarded Category 249 | Statuscode : 0 250 | Active : False 251 | 252 | Id : b803f4ef-066b-e511-810b-fc15b428ced0 253 | Name : Chef/Puppet in Datacenter 254 | AwardName : Cloud and Datacenter Management 255 | AwardCategory : My Awarded Category 256 | Statuscode : 0 257 | Active : False 258 | 259 | Id : be03f4ef-066b-e511-810b-fc15b428ced0 260 | Name : Container Management 261 | AwardName : Cloud and Datacenter Management 262 | AwardCategory : My Awarded Category 263 | Statuscode : 0 264 | Active : False 265 | 266 | Id : c603f4ef-066b-e511-810b-fc15b428ced0 267 | Name : Datacenter Management 268 | AwardName : Cloud and Datacenter Management 269 | AwardCategory : My Awarded Category 270 | Statuscode : 0 271 | Active : False 272 | 273 | Id : 90c301bb-189a-e411-93f2-9cb65495d3c4 274 | Name : Enterprise Security 275 | AwardName : Cloud and Datacenter Management 276 | AwardCategory : My Awarded Category 277 | Statuscode : 0 278 | Active : False 279 | 280 | Id : 7ac301bb-189a-e411-93f2-9cb65495d3c4 281 | Name : Group Policy 282 | AwardName : Cloud and Datacenter Management 283 | AwardCategory : My Awarded Category 284 | Statuscode : 0 285 | Active : False 286 | 287 | Id : d003f4ef-066b-e511-810b-fc15b428ced0 288 | Name : High Availability 289 | AwardName : Cloud and Datacenter Management 290 | AwardCategory : My Awarded Category 291 | Statuscode : 0 292 | Active : False 293 | 294 | Id : 9ec301bb-189a-e411-93f2-9cb65495d3c4 295 | Name : Hyper-V 296 | AwardName : Cloud and Datacenter Management 297 | AwardCategory : My Awarded Category 298 | Statuscode : 0 299 | Active : False 300 | 301 | Id : e203f4ef-066b-e511-810b-fc15b428ced0 302 | Name : Linux on Hyper-V 303 | AwardName : Cloud and Datacenter Management 304 | AwardCategory : My Awarded Category 305 | Statuscode : 0 306 | Active : False 307 | 308 | Id : e403f4ef-066b-e511-810b-fc15b428ced0 309 | Name : Linux on System Center/Operations Management Suite 310 | AwardName : Cloud and Datacenter Management 311 | AwardCategory : My Awarded Category 312 | Statuscode : 0 313 | Active : False 314 | 315 | Id : e603f4ef-066b-e511-810b-fc15b428ced0 316 | Name : Networking 317 | AwardName : Cloud and Datacenter Management 318 | AwardCategory : My Awarded Category 319 | Statuscode : 0 320 | Active : False 321 | 322 | Id : 7cc301bb-189a-e411-93f2-9cb65495d3c4 323 | Name : PowerShell 324 | AwardName : Cloud and Datacenter Management 325 | AwardCategory : My Awarded Category 326 | Statuscode : 0 327 | Active : False 328 | 329 | Id : 4604f4ef-066b-e511-810b-fc15b428ced0 330 | Name : Storage 331 | AwardName : Cloud and Datacenter Management 332 | AwardCategory : My Awarded Category 333 | Statuscode : 0 334 | Active : False 335 | 336 | Id : 98c301bb-189a-e411-93f2-9cb65495d3c4 337 | Name : Windows Server for Small and Medium Business 338 | AwardName : Cloud and Datacenter Management 339 | AwardCategory : My Awarded Category 340 | Statuscode : 0 341 | Active : False 342 | ``` 343 |
344 | 345 | 346 | ```powershell 347 | # Retrieve all Areas items 348 | Get-MVPContributionArea -All 349 | ``` 350 | 351 |
352 | Output 353 | 354 | ``` 355 | Id : b003f4ef-066b-e511-810b-fc15b428ced0 356 | Name : Azure Stack 357 | AwardName : Cloud and Datacenter Management 358 | AwardCategory : My Awarded Category 359 | Statuscode : 0 360 | Active : False 361 | 362 | Id : b803f4ef-066b-e511-810b-fc15b428ced0 363 | Name : Chef/Puppet in Datacenter 364 | AwardName : Cloud and Datacenter Management 365 | AwardCategory : My Awarded Category 366 | Statuscode : 0 367 | Active : False 368 | 369 | Id : be03f4ef-066b-e511-810b-fc15b428ced0 370 | Name : Container Management 371 | AwardName : Cloud and Datacenter Management 372 | AwardCategory : My Awarded Category 373 | Statuscode : 0 374 | Active : False 375 | 376 | Id : c603f4ef-066b-e511-810b-fc15b428ced0 377 | Name : Datacenter Management 378 | AwardName : Cloud and Datacenter Management 379 | AwardCategory : My Awarded Category 380 | Statuscode : 0 381 | Active : False 382 | 383 | Id : 90c301bb-189a-e411-93f2-9cb65495d3c4 384 | Name : Enterprise Security 385 | AwardName : Cloud and Datacenter Management 386 | AwardCategory : My Awarded Category 387 | Statuscode : 0 388 | Active : False 389 | 390 | Id : 7ac301bb-189a-e411-93f2-9cb65495d3c4 391 | Name : Group Policy 392 | AwardName : Cloud and Datacenter Management 393 | AwardCategory : My Awarded Category 394 | Statuscode : 0 395 | Active : False 396 | 397 | Id : d003f4ef-066b-e511-810b-fc15b428ced0 398 | Name : High Availability 399 | AwardName : Cloud and Datacenter Management 400 | AwardCategory : My Awarded Category 401 | Statuscode : 0 402 | Active : False 403 | 404 | Id : 9ec301bb-189a-e411-93f2-9cb65495d3c4 405 | Name : Hyper-V 406 | AwardName : Cloud and Datacenter Management 407 | AwardCategory : My Awarded Category 408 | Statuscode : 0 409 | Active : False 410 | 411 | Id : e203f4ef-066b-e511-810b-fc15b428ced0 412 | Name : Linux on Hyper-V 413 | AwardName : Cloud and Datacenter Management 414 | AwardCategory : My Awarded Category 415 | Statuscode : 0 416 | Active : False 417 | 418 | Id : e403f4ef-066b-e511-810b-fc15b428ced0 419 | Name : Linux on System Center/Operations Management Suite 420 | AwardName : Cloud and Datacenter Management 421 | AwardCategory : My Awarded Category 422 | Statuscode : 0 423 | Active : False 424 | 425 | Id : e603f4ef-066b-e511-810b-fc15b428ced0 426 | Name : Networking 427 | AwardName : Cloud and Datacenter Management 428 | AwardCategory : My Awarded Category 429 | Statuscode : 0 430 | Active : False 431 | 432 | Id : 7cc301bb-189a-e411-93f2-9cb65495d3c4 433 | Name : PowerShell 434 | AwardName : Cloud and Datacenter Management 435 | AwardCategory : My Awarded Category 436 | Statuscode : 0 437 | Active : False 438 | 439 | Id : 4604f4ef-066b-e511-810b-fc15b428ced0 440 | Name : Storage 441 | AwardName : Cloud and Datacenter Management 442 | AwardCategory : My Awarded Category 443 | Statuscode : 0 444 | Active : False 445 | 446 | Id : 98c301bb-189a-e411-93f2-9cb65495d3c4 447 | Name : Windows Server for Small and Medium Business 448 | AwardName : Cloud and Datacenter Management 449 | AwardCategory : My Awarded Category 450 | Statuscode : 0 451 | Active : False 452 | 453 | Id : 52c301bb-189a-e411-93f2-9cb65495d3c4 454 | Name : Access 455 | AwardName : Access 456 | AwardCategory : Other Award Category 457 | Statuscode : 0 458 | Active : False 459 | 460 | Id : 4ac301bb-189a-e411-93f2-9cb65495d3c4 461 | Name : Dynamics AX 462 | AwardName : Business Solutions 463 | AwardCategory : Other Award Category 464 | Statuscode : 0 465 | Active : False 466 | 467 | Id : 4cc301bb-189a-e411-93f2-9cb65495d3c4 468 | Name : Dynamics CRM 469 | AwardName : Business Solutions 470 | AwardCategory : Other Award Category 471 | Statuscode : 0 472 | Active : False 473 | 474 | Id : 4ec301bb-189a-e411-93f2-9cb65495d3c4 475 | Name : Dynamics GP 476 | AwardName : Business Solutions 477 | AwardCategory : Other Award Category 478 | Statuscode : 0 479 | Active : False 480 | 481 | Id : 50c301bb-189a-e411-93f2-9cb65495d3c4 482 | Name : Dynamics NAV 483 | AwardName : Business Solutions 484 | AwardCategory : Other Award Category 485 | Statuscode : 0 486 | Active : False 487 | 488 | Id : 60c301bb-189a-e411-93f2-9cb65495d3c4 489 | Name : Project 490 | AwardName : Business Solutions 491 | AwardCategory : Other Award Category 492 | Statuscode : 0 493 | Active : False 494 | 495 | Id : 9003f4ef-066b-e511-810b-fc15b428ced0 496 | Name : Analytics Platform System 497 | AwardName : Data Platform 498 | AwardCategory : Other Award Category 499 | Statuscode : 0 500 | Active : False 501 | 502 | Id : 9a03f4ef-066b-e511-810b-fc15b428ced0 503 | Name : Azure Data Lake 504 | AwardName : Data Platform 505 | AwardCategory : Other Award Category 506 | Statuscode : 0 507 | Active : False 508 | 509 | Id : 9c03f4ef-066b-e511-810b-fc15b428ced0 510 | Name : Azure DocumentDB 511 | AwardName : Data Platform 512 | AwardCategory : Other Award Category 513 | Statuscode : 0 514 | Active : False 515 | 516 | Id : 9e03f4ef-066b-e511-810b-fc15b428ced0 517 | Name : Azure HDInsight and Hadoop, Spark, & Storm on Azure 518 | AwardName : Data Platform 519 | AwardCategory : Other Award Category 520 | Statuscode : 0 521 | Active : False 522 | 523 | Id : a003f4ef-066b-e511-810b-fc15b428ced0 524 | Name : Azure Machine Learning 525 | AwardName : Data Platform 526 | AwardCategory : Other Award Category 527 | Statuscode : 0 528 | Active : False 529 | 530 | Id : a603f4ef-066b-e511-810b-fc15b428ced0 531 | Name : Azure Search 532 | AwardName : Data Platform 533 | AwardCategory : Other Award Category 534 | Statuscode : 0 535 | Active : False 536 | 537 | Id : ac03f4ef-066b-e511-810b-fc15b428ced0 538 | Name : Azure SQL Data Warehouse 539 | AwardName : Data Platform 540 | AwardCategory : Other Award Category 541 | Statuscode : 0 542 | Active : False 543 | 544 | Id : ae03f4ef-066b-e511-810b-fc15b428ced0 545 | Name : Azure SQL Database 546 | AwardName : Data Platform 547 | AwardCategory : Other Award Category 548 | Statuscode : 0 549 | Active : False 550 | 551 | Id : b403f4ef-066b-e511-810b-fc15b428ced0 552 | Name : Azure Stream Analytics 553 | AwardName : Data Platform 554 | AwardCategory : Other Award Category 555 | Statuscode : 0 556 | Active : False 557 | 558 | Id : c203f4ef-066b-e511-810b-fc15b428ced0 559 | Name : Cortana Intelligence Suite 560 | AwardName : Data Platform 561 | AwardCategory : Other Award Category 562 | Statuscode : 0 563 | Active : False 564 | 565 | Id : d403f4ef-066b-e511-810b-fc15b428ced0 566 | Name : Information Management (ADF, SSIS, & Data Sync) 567 | AwardName : Data Platform 568 | AwardCategory : Other Award Category 569 | Statuscode : 0 570 | Active : False 571 | 572 | Id : ed4c8e60-b30a-e611-8121-c4346bacebc4 573 | Name : Microsoft R Services 574 | AwardName : Data Platform 575 | AwardCategory : Other Award Category 576 | Statuscode : 0 577 | Active : False 578 | 579 | Id : 3204f4ef-066b-e511-810b-fc15b428ced0 580 | Name : Power BI 581 | AwardName : Data Platform 582 | AwardCategory : Other Award Category 583 | Statuscode : 0 584 | Active : False 585 | 586 | Id : 78c301bb-189a-e411-93f2-9cb65495d3c4 587 | Name : SQL Server 588 | AwardName : Data Platform 589 | AwardCategory : Other Award Category 590 | Statuscode : 0 591 | Active : False 592 | 593 | Id : 4404f4ef-066b-e511-810b-fc15b428ced0 594 | Name : SQL Server Reporting Services & Analysis Services 595 | AwardName : Data Platform 596 | AwardCategory : Other Award Category 597 | Statuscode : 0 598 | Active : False 599 | 600 | Id : d203f4ef-066b-e511-810b-fc15b428ced0 601 | Name : Identity and Access 602 | AwardName : Enterprise Mobility 603 | AwardCategory : Other Award Category 604 | Statuscode : 0 605 | Active : False 606 | 607 | Id : d603f4ef-066b-e511-810b-fc15b428ced0 608 | Name : Information Protection 609 | AwardName : Enterprise Mobility 610 | AwardCategory : Other Award Category 611 | Statuscode : 0 612 | Active : False 613 | 614 | Id : 3c04f4ef-066b-e511-810b-fc15b428ced0 615 | Name : RDS/Azure Remote App 616 | AwardName : Enterprise Mobility 617 | AwardCategory : Other Award Category 618 | Statuscode : 0 619 | Active : False 620 | 621 | Id : 4a04f4ef-066b-e511-810b-fc15b428ced0 622 | Name : System Center Configuration Manager & Microsoft Intune 623 | AwardName : Enterprise Mobility 624 | AwardCategory : Other Award Category 625 | Statuscode : 0 626 | Active : False 627 | 628 | Id : 54c301bb-189a-e411-93f2-9cb65495d3c4 629 | Name : Excel 630 | AwardName : Excel 631 | AwardCategory : Other Award Category 632 | Statuscode : 0 633 | Active : False 634 | 635 | Id : 9203f4ef-066b-e511-810b-fc15b428ced0 636 | Name : Application Integration 637 | AwardName : Microsoft Azure 638 | AwardCategory : Other Award Category 639 | Statuscode : 0 640 | Active : False 641 | 642 | Id : c803f4ef-066b-e511-810b-fc15b428ced0 643 | Name : ARM & DevOps on Azure (Chef, Puppet, Salt, Ansible, Dev/Test Lab) 644 | AwardName : Microsoft Azure 645 | AwardCategory : Other Award Category 646 | Statuscode : 0 647 | Active : False 648 | 649 | Id : 9403f4ef-066b-e511-810b-fc15b428ced0 650 | Name : Azure App Service 651 | AwardName : Microsoft Azure 652 | AwardCategory : Other Award Category 653 | Statuscode : 0 654 | Active : False 655 | 656 | Id : 9603f4ef-066b-e511-810b-fc15b428ced0 657 | Name : Azure Backup & Recovery 658 | AwardName : Microsoft Azure 659 | AwardCategory : Other Award Category 660 | Statuscode : 0 661 | Active : False 662 | 663 | Id : b603f4ef-066b-e511-810b-fc15b428ced0 664 | Name : Azure Compute (VM, VMSS, Cloud Services) 665 | AwardName : Microsoft Azure 666 | AwardCategory : Other Award Category 667 | Statuscode : 0 668 | Active : False 669 | 670 | Id : e003f4ef-066b-e511-810b-fc15b428ced0 671 | Name : Azure Container Services (Docker, Windows Server) 672 | AwardName : Microsoft Azure 673 | AwardCategory : Other Award Category 674 | Statuscode : 0 675 | Active : False 676 | 677 | Id : 45a28288-b30a-e611-8121-c4346bacebc4 678 | Name : Azure HPC/Batch 679 | AwardName : Microsoft Azure 680 | AwardCategory : Other Award Category 681 | Statuscode : 0 682 | Active : False 683 | 684 | Id : a203f4ef-066b-e511-810b-fc15b428ced0 685 | Name : Azure Media Service & CDN 686 | AwardName : Microsoft Azure 687 | AwardCategory : Other Award Category 688 | Statuscode : 0 689 | Active : False 690 | 691 | Id : a403f4ef-066b-e511-810b-fc15b428ced0 692 | Name : Azure Networking 693 | AwardName : Microsoft Azure 694 | AwardCategory : Other Award Category 695 | Statuscode : 0 696 | Active : False 697 | 698 | Id : a803f4ef-066b-e511-810b-fc15b428ced0 699 | Name : Azure Security 700 | AwardName : Microsoft Azure 701 | AwardCategory : Other Award Category 702 | Statuscode : 0 703 | Active : False 704 | 705 | Id : aa03f4ef-066b-e511-810b-fc15b428ced0 706 | Name : Azure Service Fabric 707 | AwardName : Microsoft Azure 708 | AwardCategory : Other Award Category 709 | Statuscode : 0 710 | Active : False 711 | 712 | Id : b203f4ef-066b-e511-810b-fc15b428ced0 713 | Name : Azure Storage 714 | AwardName : Microsoft Azure 715 | AwardCategory : Other Award Category 716 | Statuscode : 0 717 | Active : False 718 | 719 | Id : da03f4ef-066b-e511-810b-fc15b428ced0 720 | Name : IoT on Azure and Azure Messaging (Event Hub and Service Bus) 721 | AwardName : Microsoft Azure 722 | AwardCategory : Other Award Category 723 | Statuscode : 0 724 | Active : False 725 | 726 | Id : 3e04f4ef-066b-e511-810b-fc15b428ced0 727 | Name : SDK support on Azure (.NET, Node.js, Java, PHP, Python, GO, Ruby) 728 | AwardName : Microsoft Azure 729 | AwardCategory : Other Award Category 730 | Statuscode : 0 731 | Active : False 732 | 733 | Id : ea03f4ef-066b-e511-810b-fc15b428ced0 734 | Name : O365 API Development 735 | AwardName : Office Development 736 | AwardCategory : Other Award Category 737 | Statuscode : 0 738 | Active : False 739 | 740 | Id : ec03f4ef-066b-e511-810b-fc15b428ced0 741 | Name : Office Add-in Development 742 | AwardName : Office Development 743 | AwardCategory : Other Award Category 744 | Statuscode : 0 745 | Active : False 746 | 747 | Id : ee03f4ef-066b-e511-810b-fc15b428ced0 748 | Name : Office Development for Android 749 | AwardName : Office Development 750 | AwardCategory : Other Award Category 751 | Statuscode : 0 752 | Active : False 753 | 754 | Id : f003f4ef-066b-e511-810b-fc15b428ced0 755 | Name : Office Development for iOS 756 | AwardName : Office Development 757 | AwardCategory : Other Award Category 758 | Statuscode : 0 759 | Active : False 760 | 761 | Id : f203f4ef-066b-e511-810b-fc15b428ced0 762 | Name : Office Development with Angular.js 763 | AwardName : Office Development 764 | AwardCategory : Other Award Category 765 | Statuscode : 0 766 | Active : False 767 | 768 | Id : f403f4ef-066b-e511-810b-fc15b428ced0 769 | Name : Office Development with Node.js 770 | AwardName : Office Development 771 | AwardCategory : Other Award Category 772 | Statuscode : 0 773 | Active : False 774 | 775 | Id : f603f4ef-066b-e511-810b-fc15b428ced0 776 | Name : Office Development with PHP 777 | AwardName : Office Development 778 | AwardCategory : Other Award Category 779 | Statuscode : 0 780 | Active : False 781 | 782 | Id : 4204f4ef-066b-e511-810b-fc15b428ced0 783 | Name : SharePoint Add-in Development 784 | AwardName : Office Development 785 | AwardCategory : Other Award Category 786 | Statuscode : 0 787 | Active : False 788 | 789 | Id : ca03f4ef-066b-e511-810b-fc15b428ced0 790 | Name : Exchange 791 | AwardName : Office Servers and Services 792 | AwardCategory : Other Award Category 793 | Statuscode : 0 794 | Active : False 795 | 796 | Id : 70c301bb-189a-e411-93f2-9cb65495d3c4 797 | Name : Office365 798 | AwardName : Office Servers and Services 799 | AwardCategory : Other Award Category 800 | Statuscode : 0 801 | Active : False 802 | 803 | Id : 4004f4ef-066b-e511-810b-fc15b428ced0 804 | Name : SharePoint 805 | AwardName : Office Servers and Services 806 | AwardCategory : Other Award Category 807 | Statuscode : 0 808 | Active : False 809 | 810 | Id : 6ac301bb-189a-e411-93f2-9cb65495d3c4 811 | Name : Skype for Business 812 | AwardName : Office Servers and Services 813 | AwardCategory : Other Award Category 814 | Statuscode : 0 815 | Active : False 816 | 817 | Id : 5a04f4ef-066b-e511-810b-fc15b428ced0 818 | Name : Yammer 819 | AwardName : Office Servers and Services 820 | AwardCategory : Other Award Category 821 | Statuscode : 0 822 | Active : False 823 | 824 | Id : 5ac301bb-189a-e411-93f2-9cb65495d3c4 825 | Name : OneNote 826 | AwardName : OneNote 827 | AwardCategory : Other Award Category 828 | Statuscode : 0 829 | Active : False 830 | 831 | Id : 5cc301bb-189a-e411-93f2-9cb65495d3c4 832 | Name : Outlook 833 | AwardName : Outlook 834 | AwardCategory : Other Award Category 835 | Statuscode : 0 836 | Active : False 837 | 838 | Id : 5ec301bb-189a-e411-93f2-9cb65495d3c4 839 | Name : PowerPoint 840 | AwardName : PowerPoint 841 | AwardCategory : Other Award Category 842 | Statuscode : 0 843 | Active : False 844 | 845 | Id : 64c301bb-189a-e411-93f2-9cb65495d3c4 846 | Name : Visio 847 | AwardName : Visio 848 | AwardCategory : Other Award Category 849 | Statuscode : 0 850 | Active : False 851 | 852 | Id : aec301bb-189a-e411-93f2-9cb65495d3c4 853 | Name : .NET 854 | AwardName : Visual Studio and Development Technologies 855 | AwardCategory : Other Award Category 856 | Statuscode : 0 857 | Active : False 858 | 859 | Id : 0b2c2181-02e4-e611-80fe-3863bb34cb20 860 | Name : Accessibility 861 | AwardName : Visual Studio and Development Technologies 862 | AwardCategory : Other Award Category 863 | Statuscode : 0 864 | Active : False 865 | 866 | Id : 82c301bb-189a-e411-93f2-9cb65495d3c4 867 | Name : ASP.NET/IIS 868 | AwardName : Visual Studio and Development Technologies 869 | AwardCategory : Other Award Category 870 | Statuscode : 0 871 | Active : False 872 | 873 | Id : ba03f4ef-066b-e511-810b-fc15b428ced0 874 | Name : Clang/LLVM 875 | AwardName : Visual Studio and Development Technologies 876 | AwardCategory : Other Award Category 877 | Statuscode : 0 878 | Active : False 879 | 880 | Id : c003f4ef-066b-e511-810b-fc15b428ced0 881 | Name : Cordova 882 | AwardName : Visual Studio and Development Technologies 883 | AwardCategory : Other Award Category 884 | Statuscode : 0 885 | Active : False 886 | 887 | Id : 8ac301bb-189a-e411-93f2-9cb65495d3c4 888 | Name : Developer Security 889 | AwardName : Visual Studio and Development Technologies 890 | AwardCategory : Other Award Category 891 | Statuscode : 0 892 | Active : False 893 | 894 | Id : cc03f4ef-066b-e511-810b-fc15b428ced0 895 | Name : Front End Web Dev 896 | AwardName : Visual Studio and Development Technologies 897 | AwardCategory : Other Award Category 898 | Statuscode : 0 899 | Active : False 900 | 901 | Id : ce03f4ef-066b-e511-810b-fc15b428ced0 902 | Name : Grunt/Gulp 903 | AwardName : Visual Studio and Development Technologies 904 | AwardCategory : Other Award Category 905 | Statuscode : 0 906 | Active : False 907 | 908 | Id : dc03f4ef-066b-e511-810b-fc15b428ced0 909 | Name : Java 910 | AwardName : Visual Studio and Development Technologies 911 | AwardCategory : Other Award Category 912 | Statuscode : 0 913 | Active : False 914 | 915 | Id : de03f4ef-066b-e511-810b-fc15b428ced0 916 | Name : Javascript/Typescript 917 | AwardName : Visual Studio and Development Technologies 918 | AwardCategory : Other Award Category 919 | Statuscode : 0 920 | Active : False 921 | 922 | Id : e803f4ef-066b-e511-810b-fc15b428ced0 923 | Name : Node.js 924 | AwardName : Visual Studio and Development Technologies 925 | AwardCategory : Other Award Category 926 | Statuscode : 0 927 | Active : False 928 | 929 | Id : 3004f4ef-066b-e511-810b-fc15b428ced0 930 | Name : PHP 931 | AwardName : Visual Studio and Development Technologies 932 | AwardCategory : Other Award Category 933 | Statuscode : 0 934 | Active : False 935 | 936 | Id : 3a04f4ef-066b-e511-810b-fc15b428ced0 937 | Name : Python 938 | AwardName : Visual Studio and Development Technologies 939 | AwardCategory : Other Award Category 940 | Statuscode : 0 941 | Active : False 942 | 943 | Id : 4c04f4ef-066b-e511-810b-fc15b428ced0 944 | Name : Unity 945 | AwardName : Visual Studio and Development Technologies 946 | AwardCategory : Other Award Category 947 | Statuscode : 0 948 | Active : False 949 | 950 | Id : 8cc301bb-189a-e411-93f2-9cb65495d3c4 951 | Name : Visual C++ 952 | AwardName : Visual Studio and Development Technologies 953 | AwardCategory : Other Award Category 954 | Statuscode : 0 955 | Active : False 956 | 957 | Id : 84c301bb-189a-e411-93f2-9cb65495d3c4 958 | Name : Visual Studio ALM 959 | AwardName : Visual Studio and Development Technologies 960 | AwardCategory : Other Award Category 961 | Statuscode : 0 962 | Active : False 963 | 964 | Id : 4e04f4ef-066b-e511-810b-fc15b428ced0 965 | Name : Visual Studio Extensibility 966 | AwardName : Visual Studio and Development Technologies 967 | AwardCategory : Other Award Category 968 | Statuscode : 0 969 | Active : False 970 | 971 | Id : 5804f4ef-066b-e511-810b-fc15b428ced0 972 | Name : Xamarin 973 | AwardName : Visual Studio and Development Technologies 974 | AwardCategory : Other Award Category 975 | Statuscode : 0 976 | Active : False 977 | 978 | Id : 1183268f-7773-e511-8110-fc15b4285d7c 979 | Name : Surface Deployment & Management 980 | AwardName : Windows and Devices for IT 981 | AwardCategory : Other Award Category 982 | Statuscode : 0 983 | Active : False 984 | 985 | Id : 5404f4ef-066b-e511-810b-fc15b428ced0 986 | Name : Windows for IT 987 | AwardName : Windows and Devices for IT 988 | AwardCategory : Other Award Category 989 | Statuscode : 0 990 | Active : False 991 | 992 | Id : 5004f4ef-066b-e511-810b-fc15b428ced0 993 | Name : Windows App Development 994 | AwardName : Windows Development 995 | AwardCategory : Other Award Category 996 | Statuscode : 0 997 | Active : False 998 | 999 | Id : c1b41e30-5af2-e611-80fe-3863bb35ef70 1000 | Name : Windows Design 1001 | AwardName : Windows Development 1002 | AwardCategory : Other Award Category 1003 | Statuscode : 0 1004 | Active : False 1005 | 1006 | Id : 5604f4ef-066b-e511-810b-fc15b428ced0 1007 | Name : Windows Hardware Engineering (IoT, Mobile, and Desktop) 1008 | AwardName : Windows Development 1009 | AwardCategory : Other Award Category 1010 | Statuscode : 0 1011 | Active : False 1012 | 1013 | Id : 3ec301bb-189a-e411-93f2-9cb65495d3c4 1014 | Name : Windows Mixed Reality 1015 | AwardName : Windows Development 1016 | AwardCategory : Other Award Category 1017 | Statuscode : 0 1018 | Active : False 1019 | 1020 | Id : 66c301bb-189a-e411-93f2-9cb65495d3c4 1021 | Name : Word 1022 | AwardName : Word 1023 | AwardCategory : Other Award Category 1024 | Statuscode : 0 1025 | Active : False 1026 | 1027 | ``` 1028 |
1029 | 1030 | 1031 |
1032 | 1033 | 1034 | ### Get Your Contributions 1035 | 1036 | This will retrieve your contributions. By default it returns 5 entries. 1037 | ``` powershell 1038 | Get-MVPContribution # By default it will return 5 entries only 1039 | ``` 1040 | 1041 | You can change the limit using -Limit 1042 | ```powershell 1043 | Get-MVPContribution -Limit 100 # This will retrieve 100 entries 1044 | ``` 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | ### Create a New Contribution 1051 | ```powershell 1052 | $Splat = @{ 1053 | StartDate ='2020/10/20' 1054 | Title='Test from mvpapi.azure-api.net' 1055 | Description = 'Description sample' 1056 | ReferenceUrl='https://github.com/lazywinadmin/MVP' 1057 | AnnualQuantity='1' 1058 | SecondAnnualQuantity='0' 1059 | AnnualReach = '0' 1060 | Visibility = 'Everyone' # Get-MVPContributionVisibility 1061 | ContributionType = 'Blog/Website Post' # Get-MVPContributionType 1062 | ContributionTechnology = 'PowerShell' # Get-MVPContributionArea 1063 | } 1064 | 1065 | New-MVPContribution @Splat 1066 | ``` 1067 | 1068 | Output: 1069 | ``` 1070 | ContributionId : 123456 1071 | ContributionTypeName : Blog/Website Post 1072 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog/Website Post; EnglishName=Blog/Website Post} 1073 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1074 | AdditionalTechnologies : {} 1075 | StartDate : 2020-10-20T00:00:00 1076 | Title : Test from mvpapi.azure-api.net 1077 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1078 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1079 | AnnualQuantity : 1 1080 | SecondAnnualQuantity : 0 1081 | AnnualReach : 0 1082 | Description : Description sample 1083 | ``` 1084 | 1085 | You can double check on the MVP website, the entry was created 1086 | 1087 | ![Alt text](media/New-MVPContribution02.jpg?raw=true "New-MVPContribution") 1088 | 1089 | 1090 | If you are not sure which ContributionTechnology or ContributionType, the function has dynamicparameters that can help you find the right information, example: 1091 | 1092 | ![Alt text](media/New-MVPContribution01.jpg?raw=true "New-MVPContribution") 1093 | ![Alt text](media/New-MVPContribution03.jpg?raw=true "New-MVPContribution") 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | ### Create Multiple Contributions 1100 | 1101 | __From a CSV__ 1102 | 1103 | CSV Content [(file)](Examples/): 1104 | ``` 1105 | startdate,title,description,referenceurl,AnnualQuantity,SecondAnnualQuantity,AnnualReach,Visibility,ContributionType,ContributionTechnology 1106 | 2020-12-01,Test1,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1107 | 2020-12-02,Test2,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1108 | 2020-12-03,Test3,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1109 | 2020-12-04,Test4,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1110 | 2020-12-05,Test5,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1111 | 2020-12-06,Test6,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1112 | 2020-12-07,Test7,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1113 | 2020-12-08,Test8,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1114 | 2020-12-09,Test9,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1115 | 2020-12-10,Test10,Some content,https://github.com/lazywinadmin/MVP,1,0,0,Everyone,Blog/Website Post,PowerShell 1116 | ``` 1117 | 1118 | ```powershell 1119 | Import-Csv .\Examples\MultipleEntries.csv | New-MVPContribution 1120 | ``` 1121 | The above command will create all the entries 1122 | 1123 |
1124 | Output 1125 | 1126 | ``` 1127 | ContributionId : 731771 1128 | ContributionTypeName : Blog Site Posts 1129 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1130 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1131 | StartDate : 2017-12-01T00:00:00 1132 | Title : Test1 1133 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1134 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1135 | AnnualQuantity : 1 1136 | SecondAnnualQuantity : 0 1137 | AnnualReach : 0 1138 | Description : Some content 1139 | 1140 | ContributionId : 731772 1141 | ContributionTypeName : Blog Site Posts 1142 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1143 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1144 | StartDate : 2017-12-02T00:00:00 1145 | Title : Test2 1146 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1147 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1148 | AnnualQuantity : 1 1149 | SecondAnnualQuantity : 0 1150 | AnnualReach : 0 1151 | Description : Some content 1152 | 1153 | ContributionId : 731773 1154 | ContributionTypeName : Blog Site Posts 1155 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1156 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1157 | StartDate : 2017-12-03T00:00:00 1158 | Title : Test3 1159 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1160 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1161 | AnnualQuantity : 1 1162 | SecondAnnualQuantity : 0 1163 | AnnualReach : 0 1164 | Description : Some content 1165 | 1166 | ContributionId : 731774 1167 | ContributionTypeName : Blog Site Posts 1168 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1169 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1170 | StartDate : 2017-12-04T00:00:00 1171 | Title : Test4 1172 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1173 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1174 | AnnualQuantity : 1 1175 | SecondAnnualQuantity : 0 1176 | AnnualReach : 0 1177 | Description : Some content 1178 | 1179 | ContributionId : 731775 1180 | ContributionTypeName : Blog Site Posts 1181 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1182 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1183 | StartDate : 2017-12-05T00:00:00 1184 | Title : Test5 1185 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1186 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1187 | AnnualQuantity : 1 1188 | SecondAnnualQuantity : 0 1189 | AnnualReach : 0 1190 | Description : Some content 1191 | 1192 | ContributionId : 731776 1193 | ContributionTypeName : Blog Site Posts 1194 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1195 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1196 | StartDate : 2017-12-06T00:00:00 1197 | Title : Test6 1198 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1199 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1200 | AnnualQuantity : 1 1201 | SecondAnnualQuantity : 0 1202 | AnnualReach : 0 1203 | Description : Some content 1204 | 1205 | ContributionId : 731777 1206 | ContributionTypeName : Blog Site Posts 1207 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1208 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1209 | StartDate : 2017-12-07T00:00:00 1210 | Title : Test7 1211 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1212 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1213 | AnnualQuantity : 1 1214 | SecondAnnualQuantity : 0 1215 | AnnualReach : 0 1216 | Description : Some content 1217 | 1218 | ContributionId : 731778 1219 | ContributionTypeName : Blog Site Posts 1220 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1221 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1222 | StartDate : 2017-12-08T00:00:00 1223 | Title : Test8 1224 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1225 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1226 | AnnualQuantity : 1 1227 | SecondAnnualQuantity : 0 1228 | AnnualReach : 0 1229 | Description : Some content 1230 | 1231 | ContributionId : 731779 1232 | ContributionTypeName : Blog Site Posts 1233 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1234 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1235 | StartDate : 2017-12-09T00:00:00 1236 | Title : Test9 1237 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1238 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1239 | AnnualQuantity : 1 1240 | SecondAnnualQuantity : 0 1241 | AnnualReach : 0 1242 | Description : Some content 1243 | 1244 | ContributionId : 731780 1245 | ContributionTypeName : Blog Site Posts 1246 | ContributionType : @{Id=df6464de-179a-e411-bbc8-6c3be5a82b68; Name=Blog Site Posts; EnglishName=Blog Site Posts} 1247 | ContributionTechnology : @{Id=7cc301bb-189a-e411-93f2-9cb65495d3c4; Name=PowerShell; AwardName=; AwardCategory=} 1248 | StartDate : 2017-12-10T00:00:00 1249 | Title : Test10 1250 | ReferenceUrl : https://github.com/lazywinadmin/MVP 1251 | Visibility : @{Id=299600000; Description=Public; LocalizeKey=} 1252 | AnnualQuantity : 1 1253 | SecondAnnualQuantity : 0 1254 | AnnualReach : 0 1255 | Description : Some content 1256 | ``` 1257 |
1258 | 1259 | We can see all the entries were created on the portal 1260 | 1261 | ![Alt text](media/New-MVPContribution04.jpg?raw=true "New-MVPContribution") 1262 | 1263 | 1264 |
1265 | 1266 | ### Remove an Entry 1267 | ```powershell 1268 | Remove-MVPContribution -ID 731771 1269 | ``` 1270 | 1271 | 1272 | ### Remove Multiple Entries at once 1273 | This will delete the entries between 731771 and 731780 1274 | ```powershell 1275 | 731771..731780 | foreach-object { 1276 | if(Get-MVPContribution -ID $_){ 1277 | Remove-MVPContribution -ID $_ 1278 | } 1279 | } 1280 | ``` 1281 | 1282 | 1283 | 1284 | ### Show an MVP Profile 1285 | This will display the specified MVP IDs in the default browser. 1286 | ```powershell 1287 | Show-MVPProfile -ID 4025267 1288 | ``` 1289 | 1290 | 1291 | 1292 | 1293 | ## Authentication 1294 | 1295 | As seen in [Configure connection](#Configure) when you start using the module, you will need to authenticate against Microsoft Live OAuth. 1296 | 1297 | * Ocp-Apim-Subscription-Key : Subscription key which provides access to this API. Found in your Profile. 1298 | * Authorization : OAuth 2.0 access token obtained from MSFT Live OAuth. Supported grant types: Authorization code. 1299 | 1300 | 1301 | 1302 | ## Persistent SubscriptionKey 1303 | 1304 | If you want to save your SubscriptionKey, we recommend you store it inside your PowerShell profile. 1305 | For example, you can add the following: 1306 | 1307 | ``` 1308 | # MVP Subscription Key 1309 | $MVPSubscriptionKey = '' 1310 | Set-MVPConfiguration -SubscriptionKey $MVPSubscriptionKey 1311 | ``` 1312 | 1313 | Accessing your PowerShell profile: 1314 | 1315 | ``` 1316 | notepad $profile 1317 | ``` 1318 | 1319 | 1320 | 1321 | ## Clear the authentication from your browser 1322 | 1323 | During authentication, the module opens an Internet Explorer window to authenticate the user against the Microsoft backend. 1324 | 1325 | If you need to clear this information, you'll need to clear the Internet Explorer cache. 1326 | 1327 | 1328 | 1329 | 1330 | ## Contributing 1331 | 1332 | Would love contributors, suggestions, feedback, and other help! Feel free to open an Issue ticket. 1333 | 1334 | See [Contributing](CONTRIBUTING.md) file. 1335 | 1336 | Thanks to our contributors! 1337 | 1338 | * @p0w3rsh3ll 1339 | * @Windos 1340 | * @JPRuskins 1341 | * @PrzemyslawKlys 1342 | 1343 | 1344 | 1345 | ## More Information 1346 | 1347 | * [Microsoft - mvpapi.portal.azure-api.net](https://mvpapi.portal.azure-api.net/) 1348 | * [Microsoft - mvp-api-video](https://aka.ms/mvp-api-video) 1349 | * [MVP.PSGitHub module](https://github.com/markekraus/MVP.PSGitHub/) by @markekraus - PowerShell Utility Functions for Adding PowerShell GitHub Contributions to the Microsoft MVP API 1350 | * [Update Youtube video contributions script](https://github.com/julioarruda/UpdateMVPContributions) by @julioarruda - PowerShell script to update the View count in existing Microsoft MVP Contributions 1351 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Starter pipeline 2 | # Start with a minimal pipeline that you can customize to build and deploy your code. 3 | # Add steps that build, run tests, deploy, and more: 4 | # https://aka.ms/yaml 5 | 6 | trigger: 7 | - master 8 | resources: 9 | - repo: self 10 | queue: 11 | name: Hosted VS2017 12 | steps: 13 | - powershell: | 14 | .\build.ps1 -InstallDependencies:$true -verbose -tasks 'setEnvironment','build','test','deploy' 15 | displayName: 'PowerShell - Build > test > deploy' 16 | env: 17 | psgallerykey: $(psgallerykey) 18 | # mvpapikey: $(mvpapikey) 19 | - task: PublishTestResults@2 20 | displayName: 'Publish Test Results **/TEST-*.xml' 21 | inputs: 22 | testResultsFormat: NUnit -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Used to start the build of a PowerShell Module 4 | .DESCRIPTION 5 | This script will install dependencies using PSDepend module and start the build tasks using InvokeBuild module 6 | .NOTES 7 | Change History 8 | -1.0 | 2019/06/17 | Francois-Xavier Cat 9 | Initial version 10 | #> 11 | [CmdletBinding()] 12 | Param( 13 | #[string[]]$tasks, 14 | [string]$GalleryRepository, 15 | [pscredential]$GalleryCredential, 16 | [string]$GalleryProxy, 17 | [string[]]$tasks, # @('build','test','deploy') 18 | [switch]$InstallDependencies 19 | ) 20 | try{ 21 | ################ 22 | # EDIT THIS PART 23 | $moduleName = "MVP" # get from source control or module ? 24 | $author = 'Francois-Xavier Cat' # fetch from source or module 25 | $description = 'MVP is a PowerShell module to interact with the Microsoft MVP website' # fetch from module ? 26 | $companyName = 'lazywinadmin.com' # fetch from module ? 27 | $projectUri = "https://github.com/lazywinadmin/$moduleName" # get from module of from source control, env var 28 | $licenseUri = "https://github.com/lazywinadmin/$moduleName/blob/master/LICENSE.md" 29 | $tags = @('MVP', 'MicrosoftMVP') 30 | ################ 31 | 32 | #$rootpath = Split-Path -path $PSScriptRoot -parent 33 | $rootpath = $PSScriptRoot 34 | $buildOutputPath = "$rootpath\buildoutput" 35 | $buildPath = "$rootpath\build" 36 | $srcPath = "$rootpath\src" 37 | $testPath = "$rootpath\tests" 38 | $modulePath = "$buildoutputPath\$moduleName" 39 | $dependenciesPath = "$rootpath\dependencies" # folder to store modules 40 | $testResult = "Test-Results.xml" 41 | 42 | $env:moduleName = $moduleName 43 | $env:modulePath = $modulePath 44 | 45 | $requirementsFilePath = "$buildPath\requirements.psd1" # contains dependencies 46 | $buildTasksFilePath = "$buildPath\tasks.build.ps1" # contains tasks to execute 47 | 48 | if($InstallDependencies) 49 | { 50 | # Setup PowerShell Gallery as PSrepository & Install PSDepend module 51 | if (-not(Get-PackageProvider -Name NuGet -ForceBootstrap)) { 52 | $providerBootstrapParams = @{ 53 | Name = 'nuget' 54 | force = $true 55 | ForceBootstrap = $true 56 | } 57 | 58 | if($PSBoundParameters['verbose']) {$providerBootstrapParams.add('verbose',$verbose)} 59 | if($GalleryProxy) { $providerBootstrapParams.Add('Proxy',$GalleryProxy) } 60 | $null = Install-PackageProvider @providerBootstrapParams 61 | Set-PSRepository -Name PSGallery -InstallationPolicy Trusted 62 | } 63 | 64 | if (-not(Get-Module -Listavailable -Name PSDepend)) { 65 | Write-Verbose -Message "BootStrapping PSDepend" 66 | "Parameter $buildOutputPath"| Write-verbose 67 | $InstallPSDependParams = @{ 68 | Name = 'PSDepend' 69 | AllowClobber = $true 70 | Confirm = $false 71 | Force = $true 72 | Scope = 'CurrentUser' 73 | } 74 | if($PSBoundParameters['verbose']) { $InstallPSDependParams.add('verbose',$verbose)} 75 | if ($GalleryRepository) { $InstallPSDependParams.Add('Repository',$GalleryRepository) } 76 | if ($GalleryProxy) { $InstallPSDependParams.Add('Proxy',$GalleryProxy) } 77 | if ($GalleryCredential) { $InstallPSDependParams.Add('ProxyCredential',$GalleryCredential) } 78 | Install-Module @InstallPSDependParams 79 | } 80 | 81 | # Install module dependencies with PSDepend 82 | $PSDependParams = @{ 83 | Force = $true 84 | Path = $requirementsFilePath 85 | } 86 | if($PSBoundParameters['verbose']) { $PSDependParams.add('verbose',$verbose)} 87 | Invoke-PSDepend @PSDependParams -Target $dependenciesPath 88 | Write-Verbose -Message "Project Bootstrapped" 89 | } 90 | 91 | # Start build using InvokeBuild module 92 | Write-Verbose -Message "Start Build" 93 | Invoke-Build -Result 'Result' -File $buildTasksFilePath -Task $tasks 94 | 95 | # Return error to CI 96 | if ($Result.Error) 97 | { 98 | $Error[-1].ScriptStackTrace | Out-String 99 | exit 1 100 | } 101 | exit 0 102 | }catch{ 103 | throw $_ 104 | } -------------------------------------------------------------------------------- /build/.psdeploy.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | $env:PSGalleryKey is set in the Continous Integration plaform 3 | $env:modulePath is set in the build.ps1 4 | $env:moduleName is set in the build.ps1 5 | $ENV:BH* are set by the BuildHelpers module 6 | #> 7 | if( 8 | $env:modulePath -and 9 | $env:BHBuildSystem -ne 'Unknown' -and 10 | $env:BHBranchName -eq "master" -and 11 | $env:BHCommitMessage -match '!deploy' 12 | ) 13 | { 14 | Deploy -Name Module { 15 | By -DeploymentType PSGalleryModule { 16 | FromSource -Source (Join-Path -path (Split-Path -Path $PSScriptRoot -Parent) -ChildPath "BuildOutput\$env:moduleName") 17 | To -Targets PSGallery 18 | WithOptions -Options @{ 19 | ApiKey = $env:PSGalleryKey 20 | } 21 | } 22 | } 23 | } 24 | else 25 | { 26 | "Skipping deployment: To deploy, ensure that...`n" + 27 | "`t* You are in a known build system (Current: $ENV:BHBuildSystem)`n" + 28 | "`t* You are committing to the master branch (Current: $ENV:BHBranchName) `n" + 29 | "`t* Your commit message includes !deploy (Current: $ENV:BHCommitMessage)" | 30 | Write-Host 31 | } -------------------------------------------------------------------------------- /build/ScriptAnalyzerSettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | # Use Severity when you want to limit the generated diagnostic records to a 3 | # subset of: Error, Warning and Information. 4 | # Uncomment the following line if you only want Errors and Warnings but 5 | # not Information diagnostic records. 6 | Severity = @('Error','Warning') 7 | 8 | # Use IncludeRules when you want to run only a subset of the default rule set. 9 | #IncludeRules = @('PSAvoidDefaultValueSwitchParameter', 10 | # 'PSMisleadingBacktick', 11 | # 'PSMissingModuleManifestField', 12 | # 'PSReservedCmdletChar', 13 | # 'PSReservedParams', 14 | # 'PSShouldProcess', 15 | # 'PSUseApprovedVerbs', 16 | # 'PSUseDeclaredVarsMoreThanAssigments') 17 | 18 | # Use ExcludeRules when you want to run most of the default set of rules except 19 | # for a few rules you wish to "exclude". Note: if a rule is in both IncludeRules 20 | # and ExcludeRules, the rule will be excluded. 21 | ExcludeRules = @( 22 | 'PSUseToExportFieldsInManifest', 23 | 'PSMissingModuleManifestField', 24 | 'PSAvoidGlobalVars' 25 | ) 26 | 27 | # You can use the following entry to supply parameters to rules that take parameters. 28 | # For instance, the PSAvoidUsingCmdletAliases rule takes a whitelist for aliases you 29 | # want to allow. 30 | Rules = @{ 31 | # Do not flag 'cd' alias. 32 | PSAvoidUsingCmdletAliases = @{Whitelist = @('Where','Select')} 33 | 34 | # Check if your script uses cmdlets that are compatible on PowerShell Core, 35 | # version 6.0.0-alpha, on Linux. 36 | # PSUseCompatibleCmdlets = @{Compatibility = @("core-6.0.0-alpha-linux")} 37 | } 38 | } -------------------------------------------------------------------------------- /build/requirements.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | PSDependOptions = @{ 3 | #Target = '.\dependencies' 4 | AddToPath = $true 5 | #DependencyType = 'PSGalleryNuget' 6 | } 7 | Pester = @{ 8 | Name = 'Pester' 9 | Parameters = @{ 10 | SkipPublisherCheck = $true 11 | } 12 | } 13 | PSScriptAnalyzer = 'Latest' 14 | ScriptAnalyzerRulesLWA = 'Latest' 15 | BuildHelpers = 'Latest' 16 | PSDeploy = 'Latest' 17 | InvokeBuild = 'Latest' 18 | } -------------------------------------------------------------------------------- /build/tasks.build.ps1: -------------------------------------------------------------------------------- 1 | 2 | task -Name nothing { 3 | "foo" 4 | } 5 | 6 | task -Name setEnvironment { 7 | # Run test build 8 | # Read the current environment, populate env vars 9 | Set-BuildEnvironment -Path $rootpath 10 | 11 | # Read back the env vars 12 | Get-Item ENV:* | Sort-Object -property Name 13 | } 14 | 15 | task -Name build { 16 | Write-Verbose -Message "Task: Build" 17 | # Retrieve public functions 18 | $publicFiles = @(Get-ChildItem -Path $srcPath\public\*.ps1 -ErrorAction SilentlyContinue) 19 | # Retrieve private functions 20 | $privateFiles = @(Get-ChildItem -Path $srcPath\private\*.ps1 -ErrorAction SilentlyContinue) 21 | 22 | # Create build output directory if does not exist yet 23 | if(-not (Test-Path -path $modulePath)) 24 | { 25 | New-Item -Path $modulePath -ItemType Directory 26 | } 27 | 28 | # Build PSM1 file with all the functions 29 | foreach($file in @($publicFiles + $privateFiles)) 30 | { 31 | Get-Content -Path $($file.fullname) | 32 | Out-File -FilePath "$modulePath\$moduleName.psm1" -Append -Encoding utf8 33 | } 34 | 35 | # Append existing PSM1 content from source 36 | if(Test-Path -Path "$srcPath\source.psm1") 37 | { 38 | get-content -path "$srcPath\source.psm1"| Out-File -FilePath "$modulePath\$moduleName.psm1" -Append -Encoding utf8 39 | } 40 | 41 | # Copy the Manifest to the build (psd1) 42 | Copy-Item -Path "$srcPath\source.psd1" -Destination $modulePath 43 | Rename-Item -Path "$modulePath\source.psd1" -NewName "$moduleName.psd1" -PassThru 44 | 45 | # Find next module version (BuildHelpers module) 46 | Write-Verbose -Message "Find next module version (BuildHelpers module)" 47 | $moduleVersion = Get-NextNugetPackageVersion -Name $moduleName 48 | 49 | $moduleManifestData = @{ 50 | Author = $author 51 | Description = $Description 52 | Copyright = "(c) $((Get-Date).year) $author. All rights reserved." 53 | Path = "$modulepath\$moduleName.psd1" 54 | FunctionsToExport = $publicFiles.basename 55 | Rootmodule = "$moduleName.psm1" 56 | ModuleVersion = $moduleVersion 57 | ProjectUri = $projectUri 58 | CompanyName = $CompanyName 59 | LicenseUri = $licenseUri 60 | Tags = $tags 61 | } 62 | Update-ModuleManifest @moduleManifestData 63 | Import-Module -Name $modulePath -RequiredVersion $moduleVersion 64 | } 65 | 66 | task -Name clean { 67 | # Output folder 68 | Remove-Item -confirm:$false -Recurse -path $buildOutputPath -ErrorAction SilentlyContinue 69 | 70 | # Delete env variables created 71 | Get-ChildItem -Path env:modulepath,env:modulename,env:bh* -ErrorAction SilentlyContinue | remove-item 72 | } 73 | 74 | task -Name deploy { 75 | Invoke-PSDeploy -Path "$buildPath\.psdeploy.ps1" -Force 76 | } 77 | 78 | task -Name test { 79 | # Run test build 80 | $PesterParams = @{ 81 | Script = @{ 82 | Path = $TestPath; 83 | Parameters = @{ 84 | moduleName = $moduleName; 85 | modulePath = $modulePath; 86 | srcPath = $srcPath; 87 | } 88 | } 89 | OutputFormat = 'NUnitXml' 90 | OutputFile = "$buildOutputPath\$testResult" 91 | PassThru = $true 92 | #Show = 'Failed', 'Fails', 'Summary' 93 | #Tags = 'Build' 94 | } 95 | 96 | $results = Invoke-Pester @PesterParams 97 | 98 | if($results.FailedCount -gt 0) 99 | { 100 | throw "Failed [$($results.FailedCount)] Pester tests." 101 | } 102 | } 103 | 104 | 105 | task -name analyze { 106 | $PSScriptAnalyzerParams = @{ 107 | IncludeDefaultRules = $true 108 | Path = "$modulePath" #\$ModuleName.psd1" 109 | Settings = "$buildPath\ScriptAnalyzerSettings.psd1" 110 | Severity = 'Warning','Error' 111 | Recurse = $true 112 | CustomRulePath = (Get-Module -Name ScriptAnalyzerRulesLWA -ListAvailable).Path 113 | } 114 | 115 | "Analyzing $ManifestPath..." 116 | $results = Invoke-ScriptAnalyzer @PSScriptAnalyzerParams 117 | if ($results) 118 | { 119 | 'One or more PSScriptAnalyzer errors/warnings were found.' 120 | 'Please investigate or add the required SuppressMessage attribute.' 121 | $results | Format-Table -AutoSize 122 | } 123 | } -------------------------------------------------------------------------------- /media/MicrosoftMVPLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/MicrosoftMVPLogo.png -------------------------------------------------------------------------------- /media/New-MVPContribution01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/New-MVPContribution01.jpg -------------------------------------------------------------------------------- /media/New-MVPContribution02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/New-MVPContribution02.jpg -------------------------------------------------------------------------------- /media/New-MVPContribution03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/New-MVPContribution03.jpg -------------------------------------------------------------------------------- /media/New-MVPContribution04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/New-MVPContribution04.jpg -------------------------------------------------------------------------------- /media/Set-MVPConfiguration01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/Set-MVPConfiguration01.jpg -------------------------------------------------------------------------------- /media/Set-MVPConfiguration02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/Set-MVPConfiguration02.jpg -------------------------------------------------------------------------------- /media/Set-MVPConfiguration03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazywinadmin/MVP/16d8ab207235b0e39044a8286358aae01243e209/media/Set-MVPConfiguration03.jpg -------------------------------------------------------------------------------- /src/private/Get-MVPOAuthAutorizationCode.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPOAuthAutorizationCode { 2 | <# 3 | .SYNOPSIS 4 | Get an Oauth 2.0 autorization code 5 | 6 | .DESCRIPTION 7 | Use the authorization code grant flow described on https://msdn.microsoft.com/en-us/library/hh243647.aspx 8 | Pop-up a window that asks you to grant permissions to the mvpapi.portal.azure-api.net application and 9 | parse the returned url to catch the authorization code 10 | 11 | .PARAMETER SubscriptionKey 12 | It's the primary key or secondary key you get in your profile on this page https://mvpapi.portal.azure-api.net/developer 13 | 14 | .PARAMETER ClientID 15 | It's the clientID you see in the url of the MVPAuth application on your https://account.live.com/consent/Manage page 16 | 17 | .EXAMPLE 18 | Set-MVPConfiguration -CliendID '0000000048193351' -SubscriptionKey $myKey 19 | #> 20 | [CmdletBinding()] 21 | Param( 22 | [Parameter(Mandatory)] 23 | [String]$ClientID, 24 | 25 | [Parameter(Mandatory)] 26 | [string]$SubscriptionKey 27 | ) 28 | Begin { 29 | $Scriptname = (Get-Variable -name MyInvocation -Scope 0 -ValueOnly).MyCommand 30 | 31 | Write-Verbose -Message "[$ScriptName] Set Variables" 32 | $scope = 'wl.emails%20wl.basic%20wl.offline_access%20wl.signin' 33 | $RedirectUri = 'https://login.live.com/oauth20_desktop.srf' 34 | $AuthorizeUri = 'https://login.live.com/oauth20_authorize.srf' 35 | $u1 = '{0}?client_id={1}&redirect_uri={2}&response_type=code&scope={3}' -f $AuthorizeUri,$ClientID,$RedirectUri,$scope 36 | 37 | Write-Verbose -Message "[$ScriptName] Scope = '$scope'" 38 | Write-Verbose -Message "[$ScriptName] RedirectUri = '$RedirectUri'" 39 | Write-Verbose -Message "[$ScriptName] AuthorizeUri = '$AuthorizeUri'" 40 | Write-Verbose -Message "[$ScriptName] u1 = '$u1'" 41 | } 42 | Process { 43 | if (-not($MVPOauth2)) { 44 | Write-Verbose -Message "[$Scriptname] No Ouath2 object detected, asking for permission" 45 | Show-MVPOAuthWindow -url $u1 46 | if ($AutorizationCode) { 47 | $HashTable = @{ 48 | Uri = 'https://login.live.com/oauth20_token.srf' 49 | Method = 'Post' 50 | ContentType = 'application/x-www-form-urlencoded' 51 | Body = 'client_id={0}&redirect_uri={1}&client_secret={2}&code={3}&grant_type=authorization_code' -f $ClientID,$RedirectUri,$SubscriptionKey,$AutorizationCode 52 | } 53 | try { 54 | $r = Invoke-RestMethod @HashTable -ErrorAction Stop 55 | Write-Verbose -Message "[$Scriptname] Successfully got oauth 2.0 access token" 56 | } catch { 57 | Throw $_ 58 | } 59 | if ($r) { 60 | $global:MVPOauth2 = $r | 61 | Add-Member -MemberType NoteProperty -Name ValidUntil -Value ((Get-Date).AddSeconds($r.expires_in-1)) -Force -PassThru 62 | } 63 | } else { 64 | Write-Warning -Message "[$Scriptname] No authorization code set" 65 | } 66 | } elseif ((Get-Date) -ge ($MVPOauth2.ValidUntil)) { 67 | 68 | Write-Verbose -Message "[$Scriptname] Expired Ouath2 access token detected, refreshing it" 69 | $HashTable = @{ 70 | Uri = 'https://login.live.com/oauth20_token.srf' 71 | Method = 'Post' 72 | ContentType = 'application/x-www-form-urlencoded' 73 | Body = 'client_id={0}&grant_type=refresh_token&redirect_uri={1}&refresh_token={2}' -f $ClientID,$RedirectUri,$MVPOauth2.refresh_token 74 | } 75 | 76 | try { 77 | $r = Invoke-RestMethod @HashTable -ErrorAction Stop 78 | Write-Verbose -Message "[$Scriptname] Successfully got oauth 2.0 refresh token" 79 | } catch { 80 | Throw $_ 81 | } 82 | if ($r) { 83 | $global:MVPOauth2 = $r | 84 | Add-Member -MemberType NoteProperty -Name ValidUntil -Value ((Get-Date).AddSeconds($r.expires_in-1)) -Force -PassThru 85 | } 86 | } else { 87 | Write-Verbose -Message "[$Scriptname] The current Oauth2 access token is still valid" 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/private/Show-MVPOAuthWindow.ps1: -------------------------------------------------------------------------------- 1 | Function Show-MVPOAuthWindow { 2 | <# 3 | .SYNOPSIS 4 | Function to show the Microsoft Authentication window 5 | .NOTES 6 | https://github.com/lazywinadmin/MVP 7 | 8 | #Credit to https://raw.githubusercontent.com/1RedOne/PSWordPress/master/Private/Show-oAuthWindow.ps1 9 | #> 10 | [CmdletBinding()] 11 | Param( 12 | [Uri]$url 13 | ) 14 | Process { 15 | 16 | $Scriptname = (Get-Variable -name MyInvocation -Scope 0 -ValueOnly).MyCommand 17 | 18 | try { 19 | Write-Verbose -Message "[$ScriptName] Load assembly System.Windows.Forms" 20 | Add-Type -AssemblyName System.Windows.Forms -ErrorAction Stop 21 | 22 | Write-Verbose -Message "[$ScriptName] Create Form" 23 | $form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width=440;Height=640} 24 | 25 | Write-Verbose -Message "[$ScriptName] Create Web browser" 26 | $web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width=420;Height=600;Url=$url} 27 | # define $uri in the immediate parent scope: 1 28 | Write-Verbose -Message "[$ScriptName] Define DocumentCompleted scriptblock" 29 | $DocComp = { 30 | $global:uri = $web.Url.AbsoluteUri 31 | if ($global:uri -match 'error=[^&]*|code=[^&]*') { 32 | $form.Close() 33 | } 34 | } 35 | $web.ScriptErrorsSuppressed = $true 36 | $web.Add_DocumentCompleted($DocComp) 37 | $form.Controls.Add($web) 38 | $form.Add_Shown({$form.Activate()}) 39 | 40 | Write-Verbose -Message "[$ScriptName] Show Dialog" 41 | $null = $form.ShowDialog() 42 | # set a the autorization code globally 43 | $global:AutorizationCode = ([regex]'^\?code=(?.+)&lc=\d{1,10}$').Matches(([uri]$uri).query).Groups | 44 | Select-Object -Last 1 -ExpandProperty value 45 | if ($global:AutorizationCode) { 46 | Write-Verbose -Message "[$ScriptName] Successfully got authorization code $($AutorizationCode)" 47 | } else { 48 | Write-Error -Message "[$ScriptName] Authorization code not catched" 49 | } 50 | } catch { 51 | $PSCmdlet.ThrowTerminatingError($_) 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/public/Get-MVPConsiderationAnswer.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPConsiderationAnswer { 2 | <# 3 | .SYNOPSIS 4 | Gets your award consideration question answers 5 | 6 | .DESCRIPTION 7 | Invoke the GetAnswers REST API to retrieve your currently active MVP award consideration question answers 8 | 9 | .EXAMPLE 10 | Get-MVPConsiderationAnswers 11 | 12 | This example gets your current MVP award consideration question answers. 13 | #> 14 | [CmdletBinding()] 15 | Param() 16 | 17 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 18 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 19 | } else { 20 | $Splat = @{ 21 | Uri = 'https://mvpapi.azure-api.net/mvp/api/awardconsideration/GetAnswers' 22 | Headers = @{ 23 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey ; 24 | Authorization = $Global:MVPAuthorizationCode 25 | } 26 | ErrorAction = 'Stop' 27 | } 28 | 29 | try { 30 | Invoke-RestMethod @Splat 31 | } catch { 32 | if ($_.ErrorDetails.Message -like '*active and pending*') { 33 | Write-Warning -Message ($_.ErrorDetails.Message | ConvertFrom-Json).Message 34 | } else { 35 | Write-Warning -Message "Failed to invoke the Get-MVPConsiderationAnswer API because $($_.Exception.Message)" 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/public/Get-MVPConsiderationQuestion.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPConsiderationQuestion { 2 | <# 3 | .SYNOPSIS 4 | Gets your award consideration question Questions 5 | 6 | .DESCRIPTION 7 | Invoke the GetCurrentQuestions REST API to retrieve your currently active MVP award consideration questions. 8 | 9 | Also returns answers if they have been registered. 10 | 11 | .EXAMPLE 12 | Get-MVPConsiderationQuestions 13 | 14 | This example gets your current MVP award consideration question Questions. 15 | #> 16 | [CmdletBinding()] 17 | Param() 18 | 19 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 20 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 21 | } else { 22 | $Splat = @{ 23 | Uri = 'https://mvpapi.azure-api.net/mvp/api/awardconsideration/getcurrentquestions' 24 | Headers = @{ 25 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey ; 26 | Authorization = $Global:MVPAuthorizationCode 27 | } 28 | ErrorAction = 'Stop' 29 | } 30 | 31 | try { 32 | Invoke-RestMethod @Splat 33 | } catch { 34 | Write-Warning -Message "Failed to invoke the Get-MVPConsiderationQuestion API because $($_.Exception.Message)" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/public/Get-MVPContribution.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPContribution { 2 | <# 3 | .SYNOPSIS 4 | Invoke the GetContributions REST API to retrieve your contributions 5 | 6 | .DESCRIPTION 7 | Gets yours contributions without parameter or by specifying the id of a contribution 8 | 9 | .PARAMETER Offset 10 | Page skip integer as int32 11 | 12 | .PARAMETER Limit 13 | Page take integer as int32 14 | 15 | .PARAMETER ID 16 | It's the id of a contribution 17 | 18 | .EXAMPLE 19 | Get-MVPContribution 20 | 21 | It gets your most recent contributions from range 1 to 5 22 | 23 | .EXAMPLE 24 | Get-MVPContribution -ID 631670 25 | 26 | It gets your contribution id 631670 27 | 28 | .NOTES 29 | https://github.com/lazywinadmin/MVP 30 | #> 31 | [CmdletBinding(DefaultParameterSetName='All')] 32 | Param( 33 | [parameter(ParameterSetName='All')] 34 | [int32]$Offset=0, 35 | 36 | [parameter(ParameterSetName='All')] 37 | [int32]$Limit=5, 38 | 39 | [parameter(ParameterSetName='ID',ValueFromPipeline,ValueFromPipelineByPropertyName)] 40 | [Alias('ContributionId')] 41 | [int32]$ID 42 | ) 43 | Process { 44 | 45 | $Scriptname = (Get-Variable -name MyInvocation -Scope 0 -ValueOnly).MyCommand 46 | 47 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 48 | Write-Warning -Message "[$Scriptname] You need to use Set-MVPConfiguration first to set the Primary Key" 49 | break 50 | } 51 | 52 | Try { 53 | Write-Verbose -message "[$Scriptname] Set Configuration" 54 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 55 | 56 | Write-Verbose -message "[$Scriptname] Build Splatting" 57 | $Splat = @{ 58 | Uri = "https://mvpapi.azure-api.net/mvp/api/contributions/$($Offset)/$($Limit)" 59 | Headers = @{ 60 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey ; 61 | Authorization = $Global:MVPAuthorizationCode 62 | } 63 | ErrorAction = 'Stop' 64 | } 65 | 66 | if ($PSBoundParameters['ID']) { 67 | Write-Verbose -message "[$Scriptname] ID Specified" 68 | $Splat.Uri = "https://mvpapi.azure-api.net/mvp/api/contributions/$($ID)" 69 | Write-Verbose -message "[$Scriptname] URI = $($Splat.Uri)" 70 | Write-Verbose -message "[$Scriptname] Querying Rest api..." 71 | Invoke-RestMethod @Splat 72 | } 73 | else{ 74 | Write-Verbose -Message "[$Scriptname] Displaying contributions range from $($Offset) to $($($Offset)+$($Limit))" 75 | Write-Verbose -message "[$Scriptname] URI = $($Splat.Uri)" 76 | Write-Verbose -message "[$Scriptname] Querying Rest api..." 77 | (Invoke-RestMethod @Splat).Contributions 78 | } 79 | } 80 | catch { 81 | $PSCmdlet.ThrowTerminatingError($_) 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/public/Get-MVPContributionArea.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPContributionArea { 2 | <# 3 | .SYNOPSIS 4 | Invoke the GetContributionAreas REST API to retrieve your contribution areas 5 | 6 | .DESCRIPTION 7 | Gets a list of Contribution areas grouped by Award Names 8 | 9 | .PARAMETER Other 10 | It gets the list of Other Award Categories 11 | 12 | .PARAMETER All 13 | It gets the list of all Award Category names 14 | 15 | .EXAMPLE 16 | Get-MVPContributionArea 17 | 18 | It gets the list of your awarded Categories 19 | 20 | .EXAMPLE 21 | Get-MVPContributionArea -Other 22 | 23 | It gets the list of Other award categories 24 | #> 25 | [CmdletBinding(DefaultParameterSetName='Mine')] 26 | Param( 27 | [parameter(ParameterSetName='Other')] 28 | [switch]$Other, 29 | 30 | [parameter(ParameterSetName='All')] 31 | [switch]$All 32 | ) 33 | Begin {} 34 | Process { 35 | 36 | 37 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 38 | Write-Warning -Message "You need to use Set-MVPConfiguration first to set the Primary Key" 39 | } else { 40 | 41 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 42 | 43 | $Splat = @{ 44 | Uri = 'https://mvpapi.azure-api.net/mvp/api/contributions/contributionareas' 45 | Headers = @{ 46 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 47 | Authorization = $Global:MVPAuthorizationCode 48 | } 49 | ErrorAction = 'Stop' 50 | } 51 | try { 52 | $careas = (Invoke-RestMethod @Splat) 53 | 54 | Switch($PsCmdlet.ParameterSetName) { 55 | 'Mine' { 56 | ($careas | Where-Object -FilterScript { $_.AwardCategory -eq 'My Awarded Category' }).Contributions 57 | break 58 | } 59 | 'Other' { 60 | ($careas | Where-Object -FilterScript { $_.AwardCategory -eq 'Other Award Category' }).Contributions.contributionarea 61 | break 62 | } 63 | 'All' { 64 | $careas.Contributions.contributionarea 65 | break 66 | } 67 | default{} 68 | 69 | } 70 | } catch { 71 | Write-Warning -Message "Failed to invoke the GetContributionAreas API because $($_.Exception.Message)" 72 | } 73 | } 74 | } 75 | End {} 76 | } -------------------------------------------------------------------------------- /src/public/Get-MVPContributionType.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPContributionType { 2 | <# 3 | .SYNOPSIS 4 | Invoke the GetContributionTypes REST API to retrieve contribution types 5 | 6 | .DESCRIPTION 7 | Gets a list of contribution types 8 | 9 | 10 | .EXAMPLE 11 | Get-MVPContributionType 12 | 13 | It gets the list of contribution types 14 | #> 15 | [CmdletBinding()] 16 | Param() 17 | Begin {} 18 | Process { 19 | 20 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 21 | 22 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 23 | 24 | } else { 25 | 26 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 27 | 28 | $Splat = @{ 29 | Uri = 'https://mvpapi.azure-api.net/mvp/api/contributions/contributiontypes' 30 | Headers = @{ 31 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 32 | Authorization = $Global:MVPAuthorizationCode 33 | } 34 | ErrorAction = 'Stop' 35 | } 36 | try { 37 | [PSCustomObject[]](Invoke-RestMethod @Splat) 38 | } catch { 39 | Write-Warning -Message "Failed to invoke the GetContributionTypes API because $($_.Exception.Message)" 40 | } 41 | } 42 | } 43 | End {} 44 | } -------------------------------------------------------------------------------- /src/public/Get-MVPContributionVisibility.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPContributionVisibility { 2 | <# 3 | .SYNOPSIS 4 | Invoke the GetSharingPreferences REST API to retrieve contribution visibility types 5 | 6 | .DESCRIPTION 7 | Gets a list of Sharing Preference / Visibility Types for Contributions 8 | 9 | .EXAMPLE 10 | Get-MVPContributionVisibility 11 | 12 | #> 13 | [CmdletBinding()] 14 | Param() 15 | Begin {} 16 | Process { 17 | 18 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 19 | 20 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 21 | 22 | } else { 23 | 24 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 25 | 26 | $Splat = @{ 27 | Uri = 'https://mvpapi.azure-api.net/mvp/api/contributions/sharingpreferences' 28 | Headers = @{ 29 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 30 | Authorization = $Global:MVPAuthorizationCode 31 | } 32 | ErrorAction = 'Stop' 33 | } 34 | 35 | try { 36 | (Invoke-RestMethod @Splat) 37 | } catch { 38 | Write-Warning -Message "Failed to invoke the GetSharingPreferences API because $($_.Exception.Message)" 39 | } 40 | } 41 | } 42 | End {} 43 | } -------------------------------------------------------------------------------- /src/public/Get-MVPOnlineIdentity.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPOnlineIdentity { 2 | <# 3 | .SYNOPSIS 4 | Invoke the GetOnlineIdentities REST API 5 | 6 | .DESCRIPTION 7 | Gets a list of your online identities in your MVP profile 8 | 9 | .PARAMETER Id 10 | It's the id of the online identity in a int32 format 11 | 12 | .PARAMETER NominationsId 13 | It's your MVP Nomination Id in a GUID format a.k.a your OnlineIdentityId 14 | 15 | .EXAMPLE 16 | Get-MVPOnlineIdentity 17 | 18 | It gets the list of the online identities in your MVP profile 19 | 20 | .EXAMPLE 21 | Get-MVPOnlineIdentity -Id 55977 22 | 23 | It gets the online identity by its id 24 | 25 | .EXAMPLE 26 | Get-MVPOnlineIdentity -NominationsId c00b9dd2-a6a0-e411-8213-9cb654953450 27 | 28 | It gets the list of the online identities associated to your MVP nomination id 29 | 30 | #> 31 | [CmdletBinding(DefaultParameterSetName='All')] 32 | Param( 33 | 34 | [parameter(ParameterSetName='ById',ValueFromPipeline,ValueFromPipelineByPropertyName)] 35 | [Alias('PrivateSiteId')] 36 | [int32]$ID, 37 | 38 | [parameter(ParameterSetName='ByNominationID')] 39 | [Alias('OnlineIdentityId')] 40 | [Guid]$NominationsId 41 | ) 42 | Begin {} 43 | Process { 44 | 45 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 46 | 47 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 48 | 49 | } else { 50 | 51 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 52 | 53 | $Splat = @{ 54 | Uri = 'https://mvpapi.azure-api.net/mvp/api/onlineidentities' 55 | Headers = @{ 56 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 57 | Authorization = $Global:MVPAuthorizationCode 58 | } 59 | ErrorAction = 'Stop' 60 | } 61 | 62 | 63 | if ($ID) { 64 | $Splat.Uri = "https://mvpapi.azure-api.net/mvp/api/onlineidentities/$($ID)" 65 | } 66 | if ($NominationID) { 67 | $Splat.Uri = "https://mvpapi.azure-api.net/mvp/api/onlineidentities/$($NominationID)" 68 | } 69 | 70 | try { 71 | [PSCustomObject[]](Invoke-RestMethod @Splat) 72 | } catch { 73 | Write-Warning -Message "Failed to invoke the GetOnlineIdentities API because $($_.Exception.Message)" 74 | } 75 | } 76 | } 77 | End {} 78 | } -------------------------------------------------------------------------------- /src/public/Get-MVPProfile.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPProfile { 2 | <# 3 | .SYNOPSIS 4 | Invoke the GetMVPProfile REST API to retrieve an MVP profile summary 5 | 6 | .DESCRIPTION 7 | Gets a user public profile with the MVP id passed as a parameter or gets your MVP profile summary without parameter 8 | 9 | .PARAMETER ID 10 | It's an MVP id 11 | 12 | .EXAMPLE 13 | Get-MVPProfile 14 | 15 | It gets your MVP profile summary 16 | 17 | .EXAMPLE 18 | Get-MVPProfile -ID 5000475 19 | 20 | It gets the public profile of Francois-Xavier Cat 21 | 22 | .EXAMPLE 23 | Get-MVPProfile -ID '5000890' 24 | 25 | It gets the public profile of Emin Atac 26 | #> 27 | [CmdletBinding()] 28 | Param( 29 | [Parameter()] 30 | [String]$ID 31 | ) 32 | Begin {} 33 | Process { 34 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 35 | 36 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 37 | 38 | } else { 39 | 40 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 41 | 42 | $Splat = @{ 43 | Uri = 'https://mvpapi.azure-api.net/mvp/api/profile?' 44 | Headers = @{ 45 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey ; 46 | Authorization = $global:MVPAuthorizationCode 47 | } 48 | ErrorAction = 'Stop' ; 49 | } 50 | 51 | if ($ID) { 52 | $Splat.Uri = "https://mvpapi.azure-api.net/mvp/api/profile/$ID" 53 | } 54 | 55 | try { 56 | Invoke-RestMethod @Splat 57 | } catch { 58 | Write-Warning -Message "Failed to invoke the Get-MVPProfile API because $($_.Exception.Message)" 59 | } 60 | } 61 | } 62 | End {} 63 | } -------------------------------------------------------------------------------- /src/public/Get-MVPProfileImage.ps1: -------------------------------------------------------------------------------- 1 | Function Get-MVPProfileImage { 2 | <# 3 | .SYNOPSIS 4 | Invoke the GetMVPProfileImage REST API to retrieve your MVP profile image 5 | 6 | .DESCRIPTION 7 | Gets your MVP profile image 8 | 9 | .EXAMPLE 10 | Get-MVPProfileImage 11 | 12 | It gets your MVP profile image. 13 | #> 14 | [CmdletBinding()] 15 | Param() 16 | 17 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 18 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 19 | } else { 20 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 21 | 22 | $Splat = @{ 23 | Uri = 'https://mvpapi.azure-api.net/mvp/api/profile/photo' 24 | Headers = @{ 25 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey ; 26 | Authorization = $Global:MVPAuthorizationCode 27 | } 28 | ErrorAction = 'Stop' 29 | } 30 | 31 | try { 32 | Invoke-RestMethod @Splat 33 | } catch { 34 | Write-Warning -Message "Failed to invoke the Get-MVPProfile API because $($_.Exception.Message)" 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/public/Lock-MVPConsiderationAnswer.ps1: -------------------------------------------------------------------------------- 1 | Function Lock-MVPConsiderationAnswer { 2 | <# 3 | .SYNOPSIS 4 | Invoke the SubmitAnswers REST API 5 | 6 | .DESCRIPTION 7 | Submits and finalizes all answers for award consideration questions 8 | 9 | .EXAMPLE 10 | Lock-MVPConsiderationAnswer 11 | 12 | This will submit and finalize all answers for MVP award consideration questions. No changes will be possible after execution. 13 | 14 | .NOTES 15 | https://github.com/lazywinadmin/MVP 16 | #> 17 | [CmdletBinding(SupportsShouldProcess = $true, 18 | ConfirmImpact = 'High')] 19 | Param() 20 | Begin {} 21 | Process { 22 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 23 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 24 | } else { 25 | $Splat = @{ 26 | Uri = 'https://mvpapi.azure-api.net/mvp/api/awardconsideration/SubmitAnswers' 27 | Headers = @{ 28 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 29 | Authorization = $Global:MVPAuthorizationCode 30 | } 31 | Method = 'POST' 32 | ErrorAction = 'Stop' 33 | } 34 | 35 | try { 36 | Write-Verbose -Message "About to submit and finalize all MVP award consideration questions." 37 | if ($PSCmdlet.ShouldProcess('Submitting and finalizing all MVP award consideration questions.')) { 38 | Invoke-RestMethod @Splat 39 | } 40 | } catch { 41 | Write-Warning -Message "Failed to invoke the SubmitAnswers API because $($_.Exception.Message)" 42 | } 43 | } 44 | } 45 | End {} 46 | } -------------------------------------------------------------------------------- /src/public/New-MVPConsiderationAnswer.ps1: -------------------------------------------------------------------------------- 1 | Function New-MVPConsiderationAnswer { 2 | <# 3 | .SYNOPSIS 4 | Invoke the SaveAnswers REST API 5 | 6 | .DESCRIPTION 7 | Creates a new answer for an award consideration question 8 | 9 | .PARAMETER Answer 10 | Specifies the MVP's answer to the given award consideration question 11 | 12 | .PARAMETER AwardQuestionId 13 | Specifies the ID of the question being answered. 14 | 15 | This can be retrieved using the Get-MVPConsiderationQuestion function. 16 | 17 | .EXAMPLE 18 | $Answer = 'This is the answer to an example question.' 19 | New-MVPConsiderationAnswer -AwardQuestionId 'f8dd332f-d1f9-4185-b123-16ae0b0be34f' -Answer $Answer 20 | 21 | This will create a new answer to an MVP award consideration question using the current session opened by Set-MVPConfiguration 22 | 23 | .NOTES 24 | https://github.com/lazywinadmin/MVP 25 | #> 26 | [CmdletBinding(SupportsShouldProcess=$true)] 27 | Param( 28 | [Parameter(Mandatory, 29 | ValueFromPipelineByPropertyName=$true)] 30 | [String]$Answer, 31 | 32 | [Parameter(Mandatory, 33 | ValueFromPipelineByPropertyName=$true)] 34 | [Guid]$AwardQuestionId 35 | ) 36 | Begin {} 37 | Process { 38 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 39 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 40 | } else { 41 | $Splat = @{ 42 | Uri = 'https://mvpapi.azure-api.net/mvp/api/awardconsideration/saveanswers' 43 | Headers = @{ 44 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 45 | Authorization = $Global:MVPAuthorizationCode 46 | ContentType = 'application/json' 47 | } 48 | Method = 'POST' 49 | ContentType = 'application/json' 50 | ErrorAction = 'Stop' 51 | } 52 | 53 | $Body = @" 54 | { 55 | "AwardQuestionId": "$AwardQuestionId", 56 | "Answer": "$Answer" 57 | } 58 | "@ 59 | try { 60 | if ($pscmdlet.ShouldProcess($Body, "Create a new answer")){ 61 | Write-Verbose -Message "About to create a new answer with Body $($Body)" 62 | Invoke-RestMethod @Splat -Body $Body 63 | } 64 | } catch { 65 | Write-Warning -Message "Failed to invoke the SaveAnswers API because $($_.Exception.Message)" 66 | } 67 | } 68 | } 69 | End {} 70 | } -------------------------------------------------------------------------------- /src/public/New-MVPContribution.ps1: -------------------------------------------------------------------------------- 1 | Function New-MVPContribution { 2 | <# 3 | .SYNOPSIS 4 | Invoke the PostContribution REST API 5 | 6 | .DESCRIPTION 7 | Creates a new Contribution item 8 | 9 | .PARAMETER ContributionTechnology 10 | Specifies the Contribution technology 11 | This parameter is dynamic and is retrieving the information from Get-MVPContributionArea 12 | 13 | .PARAMETER AdditionalTechnologies 14 | Specifies an additional Contribution 15 | This parameter is dynamic and is retrieving the information from Get-MVPContributionArea 16 | 17 | .PARAMETER ContributionType 18 | Specifies the Contribution Type 19 | This parameter is dynamic and is retrieving the information from Get-MVPContributionType 20 | 21 | .PARAMETER StartDate 22 | Specifies the Date of the activity 23 | 24 | .PARAMETER Title 25 | Specifies the Title of the activity 26 | 27 | .PARAMETER Description 28 | Specifies the Description of the activity 29 | 30 | .PARAMETER ReferenceUrl 31 | Specifies the Url of the activity 32 | 33 | .PARAMETER AnnualQuantity 34 | Specifies the Annual quantity. 35 | Default is 1 36 | 37 | .PARAMETER SecondAnnualQuantity 38 | Specifies the Second Annual quantity. 39 | Default is 0 40 | 41 | .PARAMETER AnnualReach 42 | Specifies the Annual Reach 43 | Default is 0 44 | 45 | .PARAMETER Visibility 46 | Specifies the audience that will be able to see your activity 47 | Values: 'EveryOne','Microsoft','MVP Community','Microsoft Only' 48 | Default = 'Microsoft' 49 | 50 | .EXAMPLE 51 | $Splat = @{ 52 | startdate ='2018/10/10' 53 | Title='Test from mvpapi.azure-api.net' 54 | Description = 'Description sample' 55 | ReferenceUrl='https://github.com/lazywinadmin/MVP' 56 | AnnualQuantity='1' 57 | SecondAnnualQuantity='0' 58 | AnnualReach = '0' 59 | Visibility = 'EveryOne' # Get-MVPContributionVisibility 60 | ContributionType = 'Blog Site Posts' # Get-MVPContributionType 61 | ContributionTechnology = 'PowerShell' # Get-MVPContributionArea 62 | AdditionalTechnologies = 'ARM & DevOps on Azure (Chef, Puppet, Salt, Ansible, Dev/Test Lab)' # Get-MVPContributionArea 63 | } 64 | New-MVPContribution @splat 65 | 66 | This will create a new MVP Contribution using the current session opened by Set-MVPConfiguration 67 | 68 | .NOTES 69 | https://github.com/lazywinadmin/MVP 70 | #> 71 | [CmdletBinding(SupportsShouldProcess=$true)] 72 | Param( 73 | [Parameter(ValueFromPipelineByPropertyName=$true)] 74 | [String]$StartDate = (Get-Date -Format 'yyyy/MM/dd'), 75 | 76 | [Parameter(ValueFromPipelineByPropertyName=$true)] 77 | [String]$Title='Test from mvpapi.azure-api.net', 78 | 79 | [Parameter(ValueFromPipelineByPropertyName=$true)] 80 | [String]$Description='Description sample', 81 | 82 | [Parameter(ValueFromPipelineByPropertyName=$true)] 83 | [String]$ReferenceUrl='https://github.com/lazywinadmin/MVP', 84 | 85 | [Parameter(ValueFromPipelineByPropertyName=$true)] 86 | [String]$AnnualQuantity='1', 87 | 88 | [Parameter(ValueFromPipelineByPropertyName=$true)] 89 | [String]$SecondAnnualQuantity='0', 90 | 91 | [Parameter(ValueFromPipelineByPropertyName=$true)] 92 | [String]$AnnualReach = '0', 93 | 94 | [Parameter(ValueFromPipelineByPropertyName=$true)] 95 | [ValidateSet('EveryOne','Microsoft','MVP Community','Microsoft Only')] 96 | [String]$Visibility = 'Microsoft' 97 | ) 98 | DynamicParam { 99 | # Create dictionary 100 | $Dictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary 101 | 102 | # ContributionTechnology 103 | $ParameterName = 'ContributionTechnology' 104 | $AttribColl1 = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] 105 | $Param1Att = New-Object -TypeName System.Management.Automation.ParameterAttribute 106 | $Param1Att.Mandatory = $true 107 | $Param1Att.ValueFromPipelineByPropertyName = $true 108 | $Param1Att.ParameterSetName = '__AllParameterSets' 109 | $AttribColl1.Add($Param1Att) 110 | $AttribColl1.Add((New-Object -TypeName System.Management.Automation.ValidateSetAttribute -ArgumentList (Get-MVPContributionArea -All | Select-Object -ExpandProperty Name))) 111 | $Dictionary.Add($ParameterName,(New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList ($ParameterName, [string], $AttribColl1))) 112 | 113 | # ContributionType 114 | $ParameterID = 'ContributionType' 115 | $AttribColl2 = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] 116 | $Param2Att = New-Object -TypeName System.Management.Automation.ParameterAttribute 117 | $Param2Att.Mandatory = $true 118 | $Param2Att.ValueFromPipelineByPropertyName=$true 119 | $Param2Att.ParameterSetName = '__AllParameterSets' 120 | $AttribColl2.Add($Param2Att) 121 | $AttribColl2.Add((New-Object -TypeName System.Management.Automation.ValidateSetAttribute -ArgumentList (Get-MVPContributionType | Select-Object -ExpandProperty Name))) 122 | $Dictionary.Add($ParameterID,(New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList ($ParameterID, [string], $AttribColl2))) 123 | 124 | # AdditionalTechnologies 125 | $ParameterName3 = 'AdditionalTechnologies' 126 | $AttribColl3 = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] 127 | $Param3Att = New-Object -TypeName System.Management.Automation.ParameterAttribute 128 | $Param3Att.Mandatory = $false 129 | $Param3Att.ValueFromPipelineByPropertyName = $true 130 | $Param3Att.ParameterSetName = '__AllParameterSets' 131 | $AttribColl3.Add($Param3Att) 132 | $AttribColl3.Add((New-Object -TypeName System.Management.Automation.ValidateSetAttribute -ArgumentList (Get-MVPContributionArea -All | Select-Object -ExpandProperty Name))) 133 | $Dictionary.Add($ParameterName3,(New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList ($ParameterName3, [string[]], $AttribColl3))) 134 | 135 | #Return dictionary 136 | $Dictionary 137 | } 138 | Begin {} 139 | Process { 140 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 141 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 142 | } else { 143 | 144 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 145 | 146 | $Splat = @{ 147 | Uri = 'https://mvpapi.azure-api.net/mvp/api/contributions' 148 | Headers = @{ 149 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 150 | Authorization = $Global:MVPAuthorizationCode 151 | ContentType = 'application/json; charset=utf-8' 152 | } 153 | Method = 'POST' 154 | ContentType = 'application/json; charset=utf-8' 155 | ErrorAction = 'Stop' 156 | } 157 | 158 | if (-not $Script:MVPCachedTypes) { 159 | $Script:MVPCachedTypes = [ordered] @{ 160 | ContributionType = Get-MVPContributionType 161 | ContributionArea = Get-MVPContributionArea -All 162 | Visibility = Get-MVPContributionVisibility 163 | } 164 | } 165 | 166 | # Verify the Contribution Type 167 | $type = $Script:MVPCachedTypes['ContributionType'] | Where-Object -FilterScript { $_.name -eq $PSBoundParameters['ContributionType'] } 168 | 169 | # Verify the Contribution Technology 170 | $Technology = $Script:MVPCachedTypes['ContributionArea'] | Where-Object -FilterScript { $_.name -eq $PSBoundParameters['ContributionTechnology'] } 171 | 172 | # Verify the Additional Technology 173 | [Array] $AdditionalTechnologies = $Script:MVPCachedTypes['ContributionArea'] | Where-Object -FilterScript { $_.name -in $PSBoundParameters['AdditionalTechnologies'] } 174 | 175 | # Get the Visibility 176 | $VisibilityObject = $Script:MVPCachedTypes['Visibility'] | Where-Object -FilterScript { $_.Description -eq $Visibility } 177 | 178 | $HashTableContribution = @{ 179 | "ContributionId" = 0 180 | "ContributionTypeName" = "$($type.name)" 181 | "ContributionType" = @{ 182 | "Id" = "$($type.id)" 183 | "Name" = "$($type.name)" 184 | "EnglishName" = "$($type.englishname)" 185 | } 186 | "ContributionTechnology" = @{ 187 | "Id" = "$($Technology.id)" 188 | "Name" = "$($Technology.name)" 189 | "AwardName" = "$($Technology.awardname)" 190 | "AwardCategory" = "$($Technology.awardcategory)" 191 | } 192 | "StartDate" = "$StartDate" 193 | "Title" = "$Title" 194 | "ReferenceUrl" = "$ReferenceUrl" 195 | "Visibility" = @{ 196 | "Id" = $($VisibilityObject.id) 197 | "Description" = "$($VisibilityObject.Description)" 198 | "LocalizeKey" = "$($VisibilityObject.LocalizeKey)" 199 | } 200 | "AnnualQuantity" = $AnnualQuantity 201 | "SecondAnnualQuantity" = $SecondAnnualQuantity 202 | "AnnualReach" = $AnnualReach 203 | "Description" = "$Description" 204 | } 205 | if ($AdditionalTechnologies) { 206 | $HashTableContribution["AdditionalTechnologies"] = @( 207 | foreach ($Technology in $AdditionalTechnologies) { 208 | @{ 209 | "Id" = "$($Technology.id)" 210 | "Name" = "$($Technology.name)" 211 | "AwardName" = "$($Technology.awardname)" 212 | "AwardCategory" = "$($Technology.awardcategory)" 213 | } 214 | } 215 | ) 216 | } 217 | $Body = $HashTableContribution | ConvertTo-Json 218 | try { 219 | if ($pscmdlet.ShouldProcess($Body, "Create a new contribution")){ 220 | Write-Verbose -Message "About to create a new contribution with Body $($Body)" 221 | Invoke-RestMethod @Splat -Body $Body 222 | } 223 | } catch { 224 | Write-Warning -Message "Failed to invoke the PostContribution API because $($_.Exception.Message)" 225 | } 226 | } 227 | } 228 | End {} 229 | } -------------------------------------------------------------------------------- /src/public/New-MVPOnlineIdentity.ps1: -------------------------------------------------------------------------------- 1 | Function New-MVPOnlineIdentity { 2 | <# 3 | .SYNOPSIS 4 | Invoke the PostOnlineIdentity REST API 5 | 6 | .DESCRIPTION 7 | Creates a new online identity 8 | 9 | .PARAMETER ID 10 | Specify the Id of the online identity in a int32 format 11 | 12 | .PARAMETER SocialNetwork 13 | Specify the Social Network 14 | 15 | .PARAMETER URL 16 | Specify the URL 17 | 18 | .PARAMETER AllowMicrosoftToQueryMyId 19 | Specify if you want to allo Microsoft to query the ID 20 | 21 | .PARAMETER Visibility 22 | Specify the Visbility (see Get-MVPContributionVisibility) 23 | 24 | .EXAMPLE 25 | New-MVPOnlineIdentity -SocialNetwork Code -Url 'test' -Verbose 26 | 27 | .EXAMPLE 28 | New-MVPOnlineIdentity -SocialNetwork Code -Url 'c:\\windows\\test' -AllowMicrosoftToQueryMyId -Visibility Microsoft -Verbose 29 | #> 30 | [CmdletBinding(SupportsShouldProcess=$true)] 31 | Param( 32 | 33 | [Parameter()] 34 | [ValidateSet('Blog','Code','Codeplex','Exchange DL Subscription Email','Facebook','GitHub','Google+','Instagram', 35 | 'Klout','LinkedIn','Meetup','Microsoft ASP.NET Forum','Microsoft IIS Forum','MS Community (MS Answers)', 36 | 'MSDN/Technet','Naver ID','Other','StackOverflow','Twitter','Website','Windows/Windows Phone Dev Center ID', 37 | 'Xbox Live gamertag','Xing','Yammer','YouTube')] 38 | [String]$SocialNetwork = 'Twitter', 39 | 40 | [Parameter()] 41 | [String]$URL='https://mvpapi.azure-api.net', 42 | 43 | [Parameter()] 44 | [Switch]$AllowMicrosoftToQueryMyId, 45 | 46 | [Parameter()] 47 | [ValidateSet('EveryOne','Microsoft','MVP Community','Microsoft Only')] 48 | [String]$Visibility = 'Microsoft' 49 | ) 50 | Begin {} 51 | Process { 52 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 53 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 54 | } else { 55 | 56 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 57 | 58 | $Splat = @{ 59 | Uri = 'https://mvpapi.azure-api.net/mvp/api/onlineidentities' 60 | Headers = @{ 61 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 62 | Authorization = $Global:MVPAuthorizationCode 63 | ContentType = 'application/json' 64 | } 65 | Method = 'POST' 66 | ContentType = 'application/json' 67 | ErrorAction = 'Stop' 68 | } 69 | 70 | # Get the Visibility 71 | $VisibilityObject = Get-MVPContributionVisibility | Where-Object -FilterScript {$_.Description -eq $Visibility } 72 | 73 | if ($AllowMicrosoftToQueryMyId) { 74 | $PrivacyConsentStatus = 'true' 75 | } else { 76 | $PrivacyConsentStatus = 'false' 77 | } 78 | switch ($SocialNetwork) { 79 | # missing 'Microsoft Connect' requires an MS account 80 | # missing 'Microsoft Office 365 forum' requires a displayname 81 | 82 | 'Blog' { $SNid = '202a47c1-33ca-e211-9b1f-00155da65f6a' ; break } 83 | 'Code' { $SNid = 'a57a64ac-33ca-e211-9b1f-00155da65f6a' ; break } 84 | 'Codeplex' { $SNid = '334c64f8-417f-e311-93ff-002dd80c017c' ; break } 85 | 'Exchange DL Subscription Email' { 86 | $SNid = 'c3fc56aa-4255-e211-811c-00155d2ee30b' ; break } 87 | 'Facebook' { $SNid = 'c5fc56aa-4255-e211-811c-00155d2ee30b' ; break } 88 | 'GitHub' { $SNid = 'ddf7c919-8081-e311-9401-00155da64d68' ; break } 89 | 'Google+' { $SNid = 'fd2a7ec7-1b60-e611-80ef-fc15b428778c' ; break } 90 | 'Instagram'{ $SNid = '0ba62aea-1b60-e611-80ef-fc15b428778c' ; break } 91 | 'Klout' { $SNid = 'c9fc56aa-4255-e211-811c-00155d2ee30b' ; break } 92 | 'LinkedIn' { $SNid = 'cbfc56aa-4255-e211-811c-00155d2ee30b' ; break } 93 | 'Meetup' { $SNid = '2b93c914-089f-e511-8114-c4346bac0abc' ; break } 94 | 'Microsoft ASP.NET Forum' { 95 | $SNid = '614bd123-4278-e311-9401-00155da64d68' ; break } 96 | 'Microsoft IIS Forum' { 97 | $SNid = 'ac372b19-4278-e311-9401-00155da64d68' ; break } 98 | 'MS Community (MS Answers)' { 99 | $SNid = 'cdfc56aa-4255-e211-811c-00155d2ee30b' ; break } 100 | 'MSDN/Technet' { 101 | $SNid = 'cffc56aa-4255-e211-811c-00155d2ee30b' ; break } 102 | 'Naver ID' { $SNid = 'd1fc56aa-4255-e211-811c-00155d2ee30b' ; break } 103 | 'Other' { $SNid = 'ddfc56aa-4255-e211-811c-00155d2ee30b' ; break } 104 | 'StackOverflow' { 105 | $SNid = '9aeda924-8081-e311-9401-00155da64d68' ; break } 106 | 'Twitter' { $SNid = 'd5fc56aa-4255-e211-811c-00155d2ee30b' ; break } 107 | 'Website' { $SNid = '222a47c1-33ca-e211-9b1f-00155da65f6a' ; break } 108 | 'Windows/Windows Phone Dev Center ID' { 109 | $SNid = 'e673a268-8081-e311-9401-00155da64d68' ; break } 110 | 'Xbox Live gamertag' { 111 | $SNid = 'c7fc56aa-4255-e211-811c-00155d2ee30b' ; break } 112 | 'Xing' { $SNid = 'd7fc56aa-4255-e211-811c-00155d2ee30b' ; break } 113 | 'Yammer' { $SNid = 'e473a268-8081-e311-9401-00155da64d68' ; break } 114 | 'YouTube' { $SNid = 'd9fc56aa-4255-e211-811c-00155d2ee30b' ; break } 115 | default {} 116 | } 117 | 118 | $Body = @" 119 | { 120 | "PrivateSiteId": 0, 121 | "SocialNetwork": { 122 | "Id": "$($SNid)", 123 | "Name": "$($SocialNetwork)", 124 | "IconUrl": "", 125 | "SystemCollectionEnabled": false 126 | }, 127 | 128 | "Url": "$($URL)", 129 | "OnlineIdentityVisibility": { 130 | "Id": $($VisibilityObject.id), 131 | "Description": "$($VisibilityObject.Description)", 132 | "LocalizeKey": "$($VisibilityObject.LocalizeKey)" 133 | }, 134 | "ContributionCollected": true, 135 | "DisplayName": "", 136 | "UserId": "", 137 | "MicrosoftAccount": "", 138 | "PrivacyConsentStatus": $($PrivacyConsentStatus), 139 | "PrivacyConsentCheckStatus": true, 140 | "PrivacyConsentCheckDate": "", 141 | "PrivacyConsentUnCheckDate": "", 142 | "Submitted": true 143 | } 144 | "@ 145 | try { 146 | if ($pscmdlet.ShouldProcess($Body, "Create a new online identity")){ 147 | Write-Verbose -Message "About to create a new identity with Body $($Body)" 148 | Invoke-RestMethod @Splat -Body $Body 149 | } 150 | } catch { 151 | Write-Warning -Message "Failed to invoke the PostOnlineIdentity API because $($_.Exception.Message)" 152 | } 153 | } 154 | } 155 | End {} 156 | } -------------------------------------------------------------------------------- /src/public/Remove-MVPConfiguration.ps1: -------------------------------------------------------------------------------- 1 | Function Remove-MVPConfiguration { 2 | <# 3 | .SYNOPSIS 4 | Remove the current MVPConfiguration 5 | .DESCRIPTION 6 | Remove the current MVPConfiguration 7 | .PARAMETER ClientID 8 | Specify your ClientID 9 | .EXAMPLE 10 | Remove-MVPConfiguration 11 | #> 12 | [CmdletBinding(SupportsShouldProcess=$true)] 13 | Param( 14 | [Parameter()] 15 | [string]$ClientID='0000000048193351' 16 | ) 17 | Begin { 18 | $RedirectUri = 'https://login.live.com/oauth20_desktop.srf' 19 | } 20 | Process { 21 | if ($pscmdlet.ShouldProcess($RedirectUri, "Remove Configuration")){ 22 | if ($MVPOauth2) { 23 | # GET https://login.live.com/oauth20_logout.srf?client_id={client_id}&redirect_uri={redirect_uri} 24 | Write-Verbose -Message 'Attempt to gracefully sign out' 25 | $HashTable = @{ 26 | Uri = 'https://login.live.com/oauth20_logout.srf?client_id={0}&redirect_uri={1}' -f $ClientID,$RedirectUri 27 | ErrorAction = 'Stop' 28 | } 29 | try { 30 | Invoke-WebRequest @HashTable 31 | $global:MVPOauth2 = $null 32 | Write-Verbose -Message 'Successfully signed out' 33 | } catch { 34 | Throw $_ 35 | } 36 | } 37 | If ($MVPPrimaryKey) { 38 | $global:MVPPrimaryKey = $null 39 | } 40 | If ($MVPAuthorizationCode) { 41 | $global:MVPAuthorizationCode = $null 42 | } 43 | } 44 | } 45 | End {} 46 | } -------------------------------------------------------------------------------- /src/public/Remove-MVPContribution.ps1: -------------------------------------------------------------------------------- 1 | Function Remove-MVPContribution { 2 | <# 3 | .SYNOPSIS 4 | Invoke the DeleteContribution REST API 5 | 6 | .DESCRIPTION 7 | Deletes a Contribution item 8 | 9 | .PARAMETER ID 10 | It's the id of a contribution 11 | 12 | .EXAMPLE 13 | Remove-MVPContribution -ID 123456 14 | 15 | .NOTES 16 | https://github.com/lazywinadmin/MVP 17 | #> 18 | [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact = 'High')] 19 | Param( 20 | [Parameter(Mandatory)] 21 | [String]$ID 22 | ) 23 | Begin {} 24 | Process { 25 | 26 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 27 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 28 | } 29 | else { 30 | 31 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 32 | 33 | $Splat = @{ 34 | Uri = "https://mvpapi.azure-api.net/mvp/api/contributions?id=$($ID)" 35 | Headers = @{ 36 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 37 | Authorization = $Global:MVPAuthorizationCode 38 | } 39 | Method = 'DELETE' 40 | ErrorAction = 'Stop' 41 | } 42 | 43 | if ($pscmdlet.ShouldProcess($ID, 'Remove contribution')) { 44 | try { 45 | Invoke-RestMethod @Splat 46 | Write-Verbose -Message "Contribution '$($ID)' deleted" 47 | } 48 | catch { 49 | Write-Warning -Message "Failed to invoke the DeleteContribution API because $($_.Exception.Message)" 50 | } 51 | } 52 | } 53 | } 54 | End {} 55 | } -------------------------------------------------------------------------------- /src/public/Remove-MVPOnlineIdentity.ps1: -------------------------------------------------------------------------------- 1 | Function Remove-MVPOnlineIdentity { 2 | <# 3 | .SYNOPSIS 4 | Invoke the DeleteOnlineIdentity REST API 5 | 6 | .DESCRIPTION 7 | Deletes an online identity 8 | 9 | .PARAMETER ID 10 | It's the id of an online identity 11 | 12 | .EXAMPLE 13 | #> 14 | [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='High')] 15 | Param( 16 | [Parameter(Mandatory)] 17 | [Alias('PrivateSiteId')] 18 | [int32]$ID 19 | ) 20 | Begin {} 21 | Process { 22 | 23 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 24 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 25 | } else { 26 | 27 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 28 | 29 | $Splat = @{ 30 | Uri = "https://mvpapi.azure-api.net/mvp/api/onlineidentities?id=$($ID)" 31 | Headers = @{ 32 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 33 | Authorization = $Global:MVPAuthorizationCode 34 | } 35 | Method = 'DELETE' 36 | ErrorAction = 'Stop' 37 | } 38 | 39 | if ($pscmdlet.ShouldProcess($ID,'Remove item')) { 40 | 41 | try { 42 | Invoke-RestMethod @Splat 43 | Write-Verbose -Message "Online Identity $($ID) deleted" 44 | } catch { 45 | Write-Warning -Message "Failed to invoke the DeleteOnlineIdentity API because $($_.Exception.Message)" 46 | } 47 | } 48 | } 49 | } 50 | End {} 51 | } -------------------------------------------------------------------------------- /src/public/Set-MVPConfiguration.ps1: -------------------------------------------------------------------------------- 1 | Function Set-MVPConfiguration { 2 | <# 3 | .SYNOPSIS 4 | Get an Oauth Autorization code 5 | 6 | .DESCRIPTION 7 | Call the private Get-MVPOAuthAutorizationCode function and define both an MVPPrimaryKey and MVPAuthorizationCode global variable 8 | 9 | .PARAMETER SubscriptionKey 10 | It's the primary key or secondary key you get in your profile on this page https://mvpapi.portal.azure-api.net/developer 11 | 12 | .PARAMETER ClientID 13 | It's the clientID you see in the url of the MVPAuth application on your https://account.live.com/consent/Manage page 14 | 15 | .EXAMPLE 16 | 17 | Set-MVPConfiguration -SubscriptionKey $myKey 18 | 19 | .NOTES 20 | https://github.com/lazywinadmin/MVP 21 | #> 22 | [CmdletBinding(SupportsShouldProcess=$true)] 23 | PARAM ( 24 | [Parameter()] 25 | [System.String]$ClientID='0000000048193351', 26 | 27 | [Parameter(Mandatory)] 28 | [System.String]$SubscriptionKey 29 | ) 30 | Process { 31 | Try{ 32 | $Scriptname = (Get-Variable -name MyInvocation -Scope 0 -ValueOnly).MyCommand 33 | 34 | Write-Verbose -Message "[$Scriptname] Get OAuth Autorization code" 35 | Get-MVPOAuthAutorizationCode -ClientID $ClientID -SubscriptionKey $SubscriptionKey -ErrorAction Stop 36 | Write-Verbose -Message "[$Scriptname] Successfully call the Get-MVPOAuthAutorizationCode function" 37 | 38 | if ($MVPOauth2) { 39 | if ($pscmdlet.ShouldProcess($ClientID, "Updating Configuration")){ 40 | Write-Verbose -Message "[$Scriptname] OAuth Autorization code retrieved" 41 | Write-Verbose -Message "[$Scriptname] Set Variables 'MVPPrimaryKey' and 'MVPAuthorizationCode'" 42 | $global:MVPPrimaryKey = $SubscriptionKey 43 | $global:MVPAuthorizationCode = ('{0} {1}' -f $MVPOauth2.token_type,$MVPOauth2.access_token) 44 | Write-Verbose -Message "[$Scriptname] Successfully set the global variables MVPPrimaryKey and MVPAuthorizationCode" 45 | } 46 | } else { 47 | Write-Error -Message "[$Scriptname] Failed to define an MVPAuthorizationCode variable" 48 | } 49 | 50 | } 51 | catch 52 | { 53 | # Return the last error 54 | $PSCmdlet.ThrowTerminatingError($_) 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/public/Set-MVPContribution.ps1: -------------------------------------------------------------------------------- 1 | Function Set-MVPContribution { 2 | <# 3 | .SYNOPSIS 4 | Invoke the PutContribution REST API 5 | 6 | .DESCRIPTION 7 | Updates a Contribution item 8 | 9 | .PARAMETER ContributionID 10 | Specify the Contribution ID to modify 11 | 12 | .PARAMETER ContributionTechnology 13 | Specify the ContributionTechnology (see Get-MVPContributionArea) 14 | 15 | .PARAMETER ContributionType 16 | Specify the ContributionType (see Get-MVPContributionType) 17 | 18 | .PARAMETER StartDate 19 | Specify the StartDate of the contribution 20 | 21 | Example '2018/10/10' 22 | .PARAMETER Title 23 | Specify the Title of your contribution 24 | 25 | .PARAMETER Description 26 | Specify the Description of your contribution 27 | 28 | .PARAMETER ReferenceUrl 29 | Specifies the Url of the activity 30 | 31 | .PARAMETER AnnualQuantity 32 | Specifies the Annual quantity. 33 | Default is 1 34 | 35 | .PARAMETER SecondAnnualQuantity 36 | Specifies the Second Annual quantity. 37 | Default is 0 38 | 39 | .PARAMETER AnnualReach 40 | Specifies the Annual Reach 41 | Default is 0 42 | 43 | .PARAMETER Visibility 44 | Specifies the audience that will be able to see your activity 45 | Values: 'EveryOne','Microsoft','MVP Community','Microsoft Only' 46 | Default = 'Microsoft' 47 | 48 | .EXAMPLE 49 | Set-MVPContribution -ContributionID 691729 -Description 'wowwwwwww!!!' 50 | 51 | .EXAMPLE 52 | Get-MVPContribution -ContributionId 700210 | Set-MVPContribution -Description "wwooowww!!" -Verbose 53 | #> 54 | [CmdletBinding(SupportsShouldProcess=$true)] 55 | Param( 56 | [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 57 | [int32]$ContributionID, 58 | 59 | [Parameter()] 60 | [string]$ContributionType='video', 61 | 62 | [Parameter()] 63 | [string]$ContributionTechnology='PowerShell', 64 | 65 | [Parameter()] 66 | [String]$StartDate = '2017/02/01', 67 | 68 | [Parameter()] 69 | [String]$Title='Test from mvpapi.azure-api.net', 70 | 71 | [Parameter()] 72 | [String]$Description='Description sample', 73 | 74 | [Parameter()] 75 | [String]$ReferenceUrl='https://github.com/lazywinadmin/MVP', 76 | 77 | [Parameter()] 78 | [String]$AnnualQuantity='0', 79 | 80 | [Parameter()] 81 | [String]$SecondAnnualQuantity='0', 82 | 83 | [Parameter()] 84 | [String]$AnnualReach = '0', 85 | 86 | [Parameter()] 87 | [ValidateSet('EveryOne','Microsoft','MVP Community','Microsoft Only')] 88 | [String]$Visibility = 'Microsoft' 89 | ) 90 | Begin {} 91 | Process { 92 | 93 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 94 | 95 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 96 | 97 | } else { 98 | 99 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 100 | 101 | $Splat = @{ 102 | Uri = 'https://mvpapi.azure-api.net/mvp/api/contributions' 103 | Headers = @{ 104 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 105 | Authorization = $Global:MVPAuthorizationCode 106 | ContentType = 'application/json' 107 | } 108 | Method = 'PUT' 109 | ContentType = 'application/json' 110 | ErrorAction = 'Stop' 111 | } 112 | 113 | # Retrieve contribution 114 | $CurrentContributionObject = Get-MVPContribution -ID $ContributionID 115 | 116 | if ($CurrentContributionObject) { 117 | 118 | if ($PSBoundParameters['ContributionType']) { 119 | # Verify the Contribution Type 120 | $type = Get-MVPContributionType | Where-Object -FilterScript {$_.name -eq $ContributionType} 121 | } else { 122 | $type = $CurrentContributionObject.ContributionType 123 | } 124 | 125 | if ($PSBoundParameters['ContributionTechnology']) { 126 | # Verify the Contribution Technology 127 | $Technology = Get-MVPContributionArea -All | Where-Object -FilterScript {$_.name -eq $ContributionTechnology} 128 | } else { 129 | $Technology = $CurrentContributionObject.ContributionTechnology 130 | } 131 | 132 | # Get the Visibility 133 | if ($PSBoundParameters['Visibility']) { 134 | $VisibilityObject = Get-MVPContributionVisibility | Where-Object -FilterScript {$_.Description -eq $Visibility } 135 | } else { 136 | $VisibilityObject=$CurrentContributionObject.Visibility 137 | } 138 | 139 | if (-not$PSBoundParameters['StartDate']) { $StartDate=$CurrentContributionObject.StartDate } 140 | if (-not$PSBoundParameters['Title']) { $Title=$CurrentContributionObject.Title } 141 | if (-not$PSBoundParameters['Description']) { $Description=$CurrentContributionObject.Description } 142 | if (-not$PSBoundParameters['ReferenceUrl']) { $ReferenceUrl=$CurrentContributionObject.ReferenceUrl } 143 | if (-not$PSBoundParameters['AnnualQuantity']) { $AnnualQuantity=$CurrentContributionObject.AnnualQuantity } 144 | if (-not$PSBoundParameters['SecondAnnualQuantity']) { $SecondAnnualQuantity=$CurrentContributionObject.SecondAnnualQuantity } 145 | if (-not$PSBoundParameters['AnnualReach']) { $AnnualReach=$CurrentContributionObject.AnnualReach } 146 | 147 | $Body = @" 148 | { 149 | "ContributionId": $ContributionID, 150 | "ContributionTypeName": "$($type.name)", 151 | "ContributionType": { 152 | "Id": "$($type.id)", 153 | "Name": "$($type.name)", 154 | "EnglishName": "$($type.englishname)" 155 | }, 156 | "ContributionTechnology": { 157 | "Id": "$($Technology.id)", 158 | "Name": "$($Technology.name)", 159 | "AwardName": "$($Technology.awardname)", 160 | "AwardCategory": "$($Technology.awardcategory)" 161 | }, 162 | "StartDate": "$StartDate", 163 | "Title": "$Title", 164 | "ReferenceUrl": "$ReferenceUrl", 165 | "Visibility": { 166 | "Id": $($VisibilityObject.id), 167 | "Description": "$($VisibilityObject.Description)", 168 | "LocalizeKey": "$($VisibilityObject.LocalizeKey)" 169 | }, 170 | "AnnualQuantity": $AnnualQuantity, 171 | "SecondAnnualQuantity": $SecondAnnualQuantity, 172 | "AnnualReach": $AnnualReach, 173 | "Description": "$Description" 174 | } 175 | "@ 176 | if ($type -and $Technology) { 177 | try { 178 | if ($pscmdlet.ShouldProcess($Body, "Updating Contribution")){ 179 | Write-Verbose -Message "About to update contribution $($ContributionID) with Body $($Body)" 180 | Invoke-RestMethod @Splat -Body $Body 181 | } 182 | } catch { 183 | Write-Warning -Message "Failed to invoke the PutContribution API because $($_.Exception.Message)" 184 | } 185 | } else { 186 | Write-Warning -Message "Either contributiontype or contributionarea isn't recognized" 187 | } 188 | } else { 189 | Write-Warning -Message "ContributionId $($ContributionID) probably not found" 190 | } 191 | } 192 | } 193 | End {} 194 | } -------------------------------------------------------------------------------- /src/public/Set-MVPOnlineIdentity.ps1: -------------------------------------------------------------------------------- 1 | Function Set-MVPOnlineIdentity { 2 | <# 3 | .SYNOPSIS 4 | Invoke the PutOnlineIdentity REST API 5 | 6 | .DESCRIPTION 7 | Updates an Online Identity 8 | 9 | .PARAMETER ID 10 | Specify the Id of the online identity in a int32 format 11 | 12 | .PARAMETER SocialNetwork 13 | Specify the Social Network 14 | 15 | .PARAMETER URL 16 | Specify the URL 17 | 18 | .PARAMETER AllowMicrosoftToQueryMyId 19 | Specify if you want to allo Microsoft to query the ID 20 | 21 | .PARAMETER Visibility 22 | Specify the Visbility (see Get-MVPContributionVisibility) 23 | 24 | .EXAMPLE 25 | Get-MVPOnlineIdentity -ID 123872 | 26 | Set-MVPOnlineIdentity -Verbose -SocialNetwork Code 27 | 28 | .EXAMPLE 29 | Get-MVPOnlineIdentity -ID 123872 | 30 | Set-MVPOnlineIdentity -Verbose -URL 'https://facebook.com/myprofile' 31 | 32 | #> 33 | [CmdletBinding(SupportsShouldProcess=$true)] 34 | Param( 35 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 36 | [Alias('PrivateSiteId')] 37 | [int32]$ID, 38 | 39 | [Parameter()] 40 | [ValidateSet('Blog','Code','Codeplex','Exchange DL Subscription Email','Facebook','GitHub','Google+','Instagram', 41 | 'Klout','LinkedIn','Meetup','Microsoft ASP.NET Forum','Microsoft IIS Forum','MS Community (MS Answers)', 42 | 'MSDN/Technet','Naver ID','Other','StackOverflow','Twitter','Website','Windows/Windows Phone Dev Center ID', 43 | 'Xbox Live gamertag','Xing','Yammer','YouTube')] 44 | [String]$SocialNetwork = 'Twitter', 45 | 46 | [Parameter()] 47 | [String]$URL = 'https://mvpapi.azure-api.net', 48 | 49 | [Switch]$AllowMicrosoftToQueryMyId, 50 | 51 | [Parameter()] 52 | [ValidateSet('EveryOne','Microsoft','MVP Community','Microsoft Only')] 53 | [String]$Visibility = 'Microsoft' 54 | ) 55 | Begin {} 56 | Process { 57 | 58 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 59 | 60 | Write-Warning -Message 'You need to use Set-MVPConfiguration first to set the Primary Key' 61 | 62 | } else { 63 | 64 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 65 | 66 | $Splat = @{ 67 | Uri = 'https://mvpapi.azure-api.net/mvp/api/onlineidentities' 68 | Headers = @{ 69 | 'Ocp-Apim-Subscription-Key' = $global:MVPPrimaryKey 70 | Authorization = $Global:MVPAuthorizationCode 71 | ContentType = 'application/json' 72 | } 73 | Method = 'PUT' 74 | ContentType = 'application/json' 75 | ErrorAction = 'Stop' 76 | } 77 | 78 | # Retrieve online identity 79 | $CurrentIdentityObject = Get-MVPOnlineIdentity -ID $ID 80 | 81 | if ($CurrentIdentityObject) { 82 | 83 | # Get the Visibility 84 | if ($PSBoundParameters['Visibility']) { 85 | $VisibilityObject = Get-MVPContributionVisibility | Where-Object -FilterScript {$_.Description -eq $Visibility } 86 | } else { 87 | $VisibilityObject=$CurrentIdentityObject.OnlineIdentityVisibility 88 | } 89 | if (-not$PSBoundParameters['SocialNetwork']) { $SocialNetwork=$CurrentIdentityObject.SocialNetwork.Name } 90 | if (-not$PSBoundParameters['URL']) { $URL=$CurrentIdentityObject.URL } 91 | if ($AllowMicrosoftToQueryMyId) { 92 | $PrivacyConsentStatus = 'true' 93 | } else { 94 | $PrivacyConsentStatus = 'false' 95 | } 96 | 97 | switch ($SocialNetwork) { 98 | # missing 'Microsoft Connect' requires an MS account 99 | # missing 'Microsoft Office 365 forum' requires a displayname 100 | 101 | 'Blog' { $SNid = '202a47c1-33ca-e211-9b1f-00155da65f6a' ; break } 102 | 'Code' { $SNid = 'a57a64ac-33ca-e211-9b1f-00155da65f6a' ; break } 103 | 'Codeplex' { $SNid = '334c64f8-417f-e311-93ff-002dd80c017c' ; break } 104 | 'Exchange DL Subscription Email' { 105 | $SNid = 'c3fc56aa-4255-e211-811c-00155d2ee30b' ; break } 106 | 'Facebook' { $SNid = 'c5fc56aa-4255-e211-811c-00155d2ee30b' ; break } 107 | 'GitHub' { $SNid = 'ddf7c919-8081-e311-9401-00155da64d68' ; break } 108 | 'Google+' { $SNid = 'fd2a7ec7-1b60-e611-80ef-fc15b428778c' ; break } 109 | 'Instagram'{ $SNid = '0ba62aea-1b60-e611-80ef-fc15b428778c' ; break } 110 | 'Klout' { $SNid = 'c9fc56aa-4255-e211-811c-00155d2ee30b' ; break } 111 | 'LinkedIn' { $SNid = 'cbfc56aa-4255-e211-811c-00155d2ee30b' ; break } 112 | 'Meetup' { $SNid = '2b93c914-089f-e511-8114-c4346bac0abc' ; break } 113 | 'Microsoft ASP.NET Forum' { 114 | $SNid = '614bd123-4278-e311-9401-00155da64d68' ; break } 115 | 'Microsoft IIS Forum' { 116 | $SNid = 'ac372b19-4278-e311-9401-00155da64d68' ; break } 117 | 'MS Community (MS Answers)' { 118 | $SNid = 'cdfc56aa-4255-e211-811c-00155d2ee30b' ; break } 119 | 'MSDN/Technet' { 120 | $SNid = 'cffc56aa-4255-e211-811c-00155d2ee30b' ; break } 121 | 'Naver ID' { $SNid = 'd1fc56aa-4255-e211-811c-00155d2ee30b' ; break } 122 | 'Other' { $SNid = 'ddfc56aa-4255-e211-811c-00155d2ee30b' ; break } 123 | 'StackOverflow' { 124 | $SNid = '9aeda924-8081-e311-9401-00155da64d68' ; break } 125 | 'Twitter' { $SNid = 'd5fc56aa-4255-e211-811c-00155d2ee30b' ; break } 126 | 'Website' { $SNid = '222a47c1-33ca-e211-9b1f-00155da65f6a' ; break } 127 | 'Windows/Windows Phone Dev Center ID' { 128 | $SNid = 'e673a268-8081-e311-9401-00155da64d68' ; break } 129 | 'Xbox Live gamertag' { 130 | $SNid = 'c7fc56aa-4255-e211-811c-00155d2ee30b' ; break } 131 | 'Xing' { $SNid = 'd7fc56aa-4255-e211-811c-00155d2ee30b' ; break } 132 | 'Yammer' { $SNid = 'e473a268-8081-e311-9401-00155da64d68' ; break } 133 | 'YouTube' { $SNid = 'd9fc56aa-4255-e211-811c-00155d2ee30b' ; break } 134 | default {} 135 | } 136 | 137 | $Body = @" 138 | { 139 | "PrivateSiteId": "$($ID)", 140 | "SocialNetwork": { 141 | "Id": "$($SNid)", 142 | "Name": "$($SocialNetwork)", 143 | "IconUrl": "", 144 | "SystemCollectionEnabled": false 145 | }, 146 | 147 | "Url": "$($URL)", 148 | "OnlineIdentityVisibility": { 149 | "Id": $($VisibilityObject.id), 150 | "Description": "$($VisibilityObject.Description)", 151 | "LocalizeKey": "$($VisibilityObject.LocalizeKey)" 152 | }, 153 | "ContributionCollected": true, 154 | "DisplayName": "", 155 | "UserId": "", 156 | "MicrosoftAccount": "", 157 | "PrivacyConsentStatus": $($PrivacyConsentStatus), 158 | "PrivacyConsentCheckStatus": true, 159 | "PrivacyConsentCheckDate": "", 160 | "PrivacyConsentUnCheckDate": "", 161 | "Submitted": true 162 | } 163 | "@ 164 | 165 | try { 166 | if ($pscmdlet.ShouldProcess($Body, "Updating Online Identity")){ 167 | Write-Verbose -Message "About to update online identity $($ID) with Body $($Body)" 168 | Invoke-RestMethod @Splat -Body $Body 169 | } 170 | } catch { 171 | Write-Warning -Message "Failed to invoke the PutOnlineIdentity API because $($_.Exception.Message)" 172 | } 173 | 174 | } else { 175 | Write-Warning -Message "Online Id $($ID) probably not found" 176 | } 177 | } 178 | } 179 | End {} 180 | } -------------------------------------------------------------------------------- /src/public/Show-MVPProfile.ps1: -------------------------------------------------------------------------------- 1 | function Show-MVPProfile { 2 | <# 3 | .SYNOPSIS 4 | Displays the MVP Profile for $ID 5 | 6 | .DESCRIPTION 7 | Opens the profile of the ID(s) provided, or your profile if no ID is specified, in the default browser. 8 | 9 | .PARAMETER ID 10 | It's an MVP ID 11 | 12 | .EXAMPLE 13 | Show-MVPProfile 14 | 15 | It shows your MVP Profile 16 | 17 | .EXAMPLE 18 | Show-MVPProfile -ID 5000475, 5000890 19 | 20 | It shows the profiles for Francois-Xavier Cat and Emin Atac 21 | 22 | .EXAMPLE 23 | Get-MVPProfile -ID 4025267 | Show-MVPProfile 24 | 25 | It shows the profile for Joel Bennett 26 | #> 27 | [CmdletBinding()] 28 | param( 29 | [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] 30 | [Alias('MvpId')] 31 | [ValidateNotNullOrEmpty()] 32 | [string[]]$ID = (Get-MVPProfile).MvpId 33 | ) 34 | process { 35 | foreach ($MVP in $ID.Where{$_}) { 36 | Start-Process -FilePath "https://mvp.microsoft.com/en-us/PublicProfile/$MVP" 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/public/Test-MVPContribution.ps1: -------------------------------------------------------------------------------- 1 | Function Test-MVPContribution { 2 | <# 3 | .SYNOPSIS 4 | Tests for matching MVP Contributions on your MVP profile 5 | 6 | .DESCRIPTION 7 | The Test-MVPContribution function looks for contributions that match supplied criteria. 8 | 9 | It can either return a boolean value, or the matching object. 10 | 11 | .PARAMETER ContributionTechnology 12 | Specifies the Contribution technology 13 | This parameter is dynamic and is retrieving the information from Get-MVPContributionArea 14 | 15 | .PARAMETER AdditionalTechnologies 16 | Specifies an additional Contribution 17 | This parameter is dynamic and is retrieving the information from Get-MVPContributionArea 18 | 19 | .PARAMETER ContributionType 20 | Specifies the Contribution Type 21 | This parameter is dynamic and is retrieving the information from Get-MVPContributionType 22 | 23 | .PARAMETER StartDate 24 | Specifies the Date of the activity 25 | 26 | .PARAMETER Title 27 | Specifies the Title of the activity 28 | 29 | .PARAMETER ReferenceUrl 30 | Specifies the Url of the activity 31 | 32 | .PARAMETER ReturnMatch 33 | Returns the matching contribution, rather than a boolean value 34 | 35 | .EXAMPLE 36 | Test-MVPContribution -Title 'PowerShell Command Precedence' -ReferenceUrl 'https://lazywinadmin.com/2017/06/CommandPrecedence.html' 37 | 38 | This command returns $true if a contribution is found with both a matching title and url 39 | 40 | .EXAMPLE 41 | Test-MVPContribution -Title 'User Group Presentation - FRPSUG' -ReturnMatch 42 | 43 | This command returns the matching contribution object if it is found 44 | 45 | .NOTES 46 | https://github.com/lazywinadmin/MVP 47 | #> 48 | [CmdletBinding()] 49 | Param( 50 | [Parameter(ValueFromPipelineByPropertyName=$true)] 51 | [String]$StartDate, 52 | 53 | [Parameter(ValueFromPipelineByPropertyName=$true)] 54 | [String]$Title, 55 | 56 | [Parameter(ValueFromPipelineByPropertyName=$true)] 57 | [String]$ReferenceUrl, 58 | 59 | [Switch]$ReturnMatch 60 | ) 61 | DynamicParam { 62 | # Borrowing dynamic parameters from New-MVPContribution 63 | # Using this should mean that supplied values are valid and correct 64 | 65 | # Create dictionary 66 | $Dictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary 67 | 68 | # ContributionTechnology 69 | $ParameterName = 'ContributionTechnology' 70 | $AttribColl1 = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] 71 | $Param1Att = New-Object -TypeName System.Management.Automation.ParameterAttribute 72 | $Param1Att.Mandatory = $false 73 | $Param1Att.ValueFromPipelineByPropertyName = $true 74 | $Param1Att.ParameterSetName = '__AllParameterSets' 75 | $AttribColl1.Add($Param1Att) 76 | $AttribColl1.Add((New-Object -TypeName System.Management.Automation.ValidateSetAttribute -ArgumentList (Get-MVPContributionArea -All | Select-Object -ExpandProperty Name))) 77 | $Dictionary.Add($ParameterName,(New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList ($ParameterName, [string], $AttribColl1))) 78 | 79 | # ContributionType 80 | $ParameterID = 'ContributionType' 81 | $AttribColl2 = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] 82 | $Param2Att = New-Object -TypeName System.Management.Automation.ParameterAttribute 83 | $Param2Att.Mandatory = $false 84 | $Param2Att.ValueFromPipelineByPropertyName=$true 85 | $Param2Att.ParameterSetName = '__AllParameterSets' 86 | $AttribColl2.Add($Param2Att) 87 | $AttribColl2.Add((New-Object -TypeName System.Management.Automation.ValidateSetAttribute -ArgumentList (Get-MVPContributionType | Select-Object -ExpandProperty Name))) 88 | $Dictionary.Add($ParameterID,(New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList ($ParameterID, [string], $AttribColl2))) 89 | 90 | # AdditionalTechnologies 91 | $ParameterName3 = 'AdditionalTechnologies' 92 | $AttribColl3 = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] 93 | $Param3Att = New-Object -TypeName System.Management.Automation.ParameterAttribute 94 | $Param3Att.Mandatory = $false 95 | $Param3Att.ValueFromPipelineByPropertyName = $true 96 | $Param3Att.ParameterSetName = '__AllParameterSets' 97 | $AttribColl3.Add($Param3Att) 98 | $AttribColl3.Add((New-Object -TypeName System.Management.Automation.ValidateSetAttribute -ArgumentList (Get-MVPContributionArea -All | Select-Object -ExpandProperty Name))) 99 | $Dictionary.Add($ParameterName3,(New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList ($ParameterName3, [string], $AttribColl3))) 100 | 101 | #Return dictionary 102 | $Dictionary 103 | } 104 | Process { 105 | $Scriptname = (Get-Variable -name MyInvocation -Scope 0 -ValueOnly).MyCommand 106 | if (-not ($global:MVPPrimaryKey -and $global:MVPAuthorizationCode)) { 107 | Write-Warning -Message "[$Scriptname] You need to use Set-MVPConfiguration first to set the Primary Key" 108 | break 109 | } 110 | Try { 111 | Write-Verbose -message "[$Scriptname] Set Configuration" 112 | Set-MVPConfiguration -SubscriptionKey $MVPPrimaryKey 113 | 114 | Write-Verbose -message "[$Scriptname] Getting all contributions, using New-MVPContribution" 115 | $Contributions = [System.Collections.ArrayList]::new() 116 | $ContribLimit = 100 117 | $More = $true 118 | 119 | while ($More) { 120 | $Offset = $ContribLimit - 100 121 | Write-Verbose -message "[$Scriptname] Getting $ContribLimit contributions with an offset of $Offset" 122 | $ContribGroup = Get-MVPContribution -Limit $ContribLimit -Offset $Offset 123 | 124 | if (($ContribGroup | Measure-Object).Count -lt 100) { 125 | Write-Verbose -message "[$Scriptname] Last set of contributions received" 126 | $More = $false 127 | } else { 128 | Write-Verbose -message "[$Scriptname] 100 contributions received, there may be more..." 129 | $ContribLimit += 100 130 | } 131 | 132 | Write-Verbose -message "[$Scriptname] Adding contributions to collection" 133 | foreach ($Contrib in $ContribGroup) { 134 | $null = $Contributions.Add($Contrib) 135 | } 136 | } 137 | 138 | Write-Verbose -message "[$Scriptname] Testing collection against supplied criteria" 139 | $MacthFound = $false 140 | foreach ($Contribution in $Contributions) { 141 | $PossibleMatch = $true 142 | foreach ($BoundParam in $PSBoundParameters.GetEnumerator()) { 143 | $Key = $BoundParam.Key 144 | if ($Contribution.$Key -notlike "$($BoundParam.Value)*") { 145 | $PossibleMatch = $false 146 | break 147 | } 148 | } 149 | 150 | if ($PossibleMatch) { 151 | $MacthFound = $true 152 | 153 | if ($ReturnMatch) { 154 | $Contribution 155 | } 156 | 157 | break 158 | } 159 | } 160 | 161 | if (!$ReturnMatch) { 162 | $MacthFound 163 | } 164 | } 165 | catch { 166 | $PSCmdlet.ThrowTerminatingError($_) 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/source.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'SpaceX' 3 | # 4 | # Generated by: Francois-Xavier Cat 5 | # 6 | # Generated on: 2018-01-17 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = '' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '0.0' 16 | 17 | # Supported PSEditions 18 | # CompatiblePSEditions = @() 19 | 20 | # ID used to uniquely identify this module 21 | GUID = '9ac077ef-4d4c-49a4-ad9b-4abe1e4ef789' 22 | 23 | # Author of this module 24 | Author = 'Francois-Xavier Cat' 25 | 26 | # Company or vendor of this module 27 | CompanyName = 'Lazywinadmin.com' 28 | 29 | # Copyright statement for this module 30 | Copyright = 'Some Copyright' 31 | 32 | # Description of the functionality provided by this module 33 | Description = 'Some description' 34 | 35 | # Minimum version of the Windows PowerShell engine required by this module 36 | PowerShellVersion = '3.0' 37 | 38 | # Name of the Windows PowerShell host required by this module 39 | # PowerShellHostName = '' 40 | 41 | # Minimum version of the Windows PowerShell host required by this module 42 | # PowerShellHostVersion = '' 43 | 44 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 45 | # DotNetFrameworkVersion = '' 46 | 47 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 48 | # CLRVersion = '' 49 | 50 | # Processor architecture (None, X86, Amd64) required by this module 51 | # ProcessorArchitecture = '' 52 | 53 | # Modules that must be imported into the global environment prior to importing this module 54 | # RequiredModules = @() 55 | 56 | # Assemblies that must be loaded prior to importing this module 57 | # RequiredAssemblies = @() 58 | 59 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 60 | # ScriptsToProcess = @() 61 | 62 | # Type files (.ps1xml) to be loaded when importing this module 63 | # TypesToProcess = @() 64 | 65 | # Format files (.ps1xml) to be loaded when importing this module 66 | # FormatsToProcess = @() 67 | 68 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 69 | # NestedModules = @() 70 | 71 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 72 | FunctionsToExport = '*' 73 | 74 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 75 | # CmdletsToExport = '*' 76 | 77 | # Variables to export from this module 78 | # VariablesToExport = '*' 79 | 80 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 81 | # AliasesToExport = '*' 82 | 83 | # DSC resources to export from this module 84 | # DscResourcesToExport = @() 85 | 86 | # List of all modules packaged with this module 87 | # ModuleList = @() 88 | 89 | # List of all files packaged with this module 90 | # FileList = @() 91 | 92 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 93 | PrivateData = @{ 94 | 95 | PSData = @{ 96 | 97 | # Tags applied to this module. These help with module discovery in online galleries. 98 | # Tags = @() 99 | 100 | # A URL to the license for this module. 101 | # LicenseUri = '' 102 | 103 | # A URL to the main website for this project. 104 | # ProjectUri = '' 105 | 106 | # A URL to an icon representing this module. 107 | # IconUri = '' 108 | 109 | # ReleaseNotes of this module 110 | # ReleaseNotes = '' 111 | 112 | } # End of PSData hashtable 113 | 114 | } # End of PrivateData hashtable 115 | 116 | # HelpInfo URI of this module 117 | # HelpInfoURI = '' 118 | 119 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 120 | # DefaultCommandPrefix = '' 121 | 122 | } 123 | 124 | -------------------------------------------------------------------------------- /src/source.psm1: -------------------------------------------------------------------------------- 1 | # things to append at the end of the Psm1 -------------------------------------------------------------------------------- /tests/module.tests.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | PARAM($modulePath,$moduleName,$srcPath) 3 | begin{ 4 | # Find the Manifest file 5 | $ManifestFile = "$modulePath\$ModuleName.psd1" 6 | 7 | # Unload any module with same name 8 | Get-Module -Name $ModuleName -All | Remove-Module -Force -ErrorAction Ignore 9 | 10 | # Import Module 11 | $ModuleInformation = Import-Module -Name $ManifestFile -Force -ErrorAction Stop -PassThru 12 | 13 | # Get the functions present in the Manifest 14 | $ExportedFunctions = $ModuleInformation.ExportedFunctions.Values.name 15 | 16 | # Public functions 17 | $publicFiles = @(Get-ChildItem -Path $srcPath\public\*.ps1 -ErrorAction SilentlyContinue) 18 | } 19 | end{ 20 | $ModuleInformation | Remove-Module -ErrorAction SilentlyContinue 21 | } 22 | process{ 23 | Describe "$ModuleName Module - Testing Manifest File (.psd1)" -Tag 'build' { 24 | Context "Manifest"{ 25 | It "Should contains RootModule"{ 26 | $ModuleInformation.RootModule | Should not BeNullOrEmpty 27 | } 28 | It "Should contains Author"{ 29 | $ModuleInformation.Author | Should not BeNullOrEmpty 30 | } 31 | It "Should contains Company Name"{ 32 | $ModuleInformation.CompanyName | Should not BeNullOrEmpty 33 | } 34 | It "Should contains Description"{ 35 | $ModuleInformation.Description | Should not BeNullOrEmpty 36 | } 37 | It "Should contains Copyright"{ 38 | $ModuleInformation.Copyright | Should not BeNullOrEmpty 39 | } 40 | It "Should contains License"{ 41 | $ModuleInformation.LicenseURI | Should not BeNullOrEmpty 42 | } 43 | It "Should contains a Project Link"{ 44 | $ModuleInformation.ProjectURI | Should not BeNullOrEmpty 45 | } 46 | It "Should contains a Tags (For the PSGallery)"{ 47 | $ModuleInformation.Tags.count | Should not BeNullOrEmpty 48 | } 49 | 50 | It "Should have equal number of Function Exported and the Public PS1 files found ($($ExportedFunctions.count) and $($publicFiles.count))"{ 51 | $ExportedFunctions.count -eq $publicFiles.count |Should -Be $true} 52 | It "Compare the missing function"{ 53 | if (-not($ExportedFunctions.count -eq $publicFiles.count)){ 54 | $Compare = Compare-Object -ReferenceObject $ExportedFunctions -DifferenceObject $publicFiles.basename 55 | $Compare.inputobject -join ',' | 56 | Should BeNullOrEmpty 57 | } 58 | } 59 | } 60 | } 61 | <# 62 | Generic tests 63 | #> 64 | Describe "$ModuleName Module - Functions Comment based help" -Tag 'build' { 65 | foreach ($function in $ExportedFunctions) { 66 | # Retrieve the Help of the function 67 | $Help = Get-Help -Name $Function -Full 68 | 69 | # Parse the function using AST 70 | $AST = [System.Management.Automation.Language.Parser]::ParseInput((Get-Content function:$Function), [ref]$null, [ref]$null) 71 | 72 | Context "$Function - Help"{ 73 | 74 | It "Synopsis"{ $help.Synopsis | Should not BeNullOrEmpty } 75 | It "Description"{ $help.Description | Should not BeNullOrEmpty } 76 | 77 | # Get the parameters declared in the Comment Based Help 78 | $RiskMitigationParameters = 'Whatif', 'Confirm' 79 | $HelpParameters = $help.parameters.parameter | Where-Object name -NotIn $RiskMitigationParameters 80 | 81 | # Get the parameters declared in the AST PARAM() Block 82 | $ASTParameters = $ast.ParamBlock.Parameters.Name.variablepath.userpath 83 | 84 | It "Parameter - Compare Count Help/AST" { 85 | $HelpParameters.name.count -eq $ASTParameters.count | Should Be $true 86 | } 87 | 88 | # Parameter Description 89 | If (-not [String]::IsNullOrEmpty($ASTParameters)) # IF ASTParameters are found 90 | { 91 | $HelpParameters | ForEach-Object { 92 | It "Parameter $($_.Name) - Should contains description"{ 93 | $_.description | Should not BeNullOrEmpty 94 | } 95 | } 96 | } 97 | 98 | # Examples 99 | it "Example - Count should be greater than 0"{ 100 | $Help.examples.example.code.count | Should BeGreaterthan 0 101 | } 102 | 103 | # Examples - Remarks (small description that comes with the example) 104 | foreach ($Example in $Help.examples.example) 105 | { 106 | it "Example - Remarks on $($Example.Title)"{ 107 | $Example.remarks | Should not BeNullOrEmpty 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | 115 | <# 116 | Test individual functions 117 | #> 118 | 119 | <#Set-MVPConfiguration -SubscriptionKey $env:mvpapikey 120 | 121 | Describe 'Get-MVPProfile' { 122 | Context 'no parameters' { 123 | $returnedData = Get-MVPProfile 124 | 125 | It 'gets result' { 126 | $returnedData|Should not BeNullOrEmpty 127 | } 128 | It 'gets a single object' { 129 | $returnedData.getType().fullname | Should Be 'System.Management.Automation.PSCustomObject' 130 | } 131 | } 132 | } 133 | #> 134 | }#process --------------------------------------------------------------------------------