From 8136e2e4fe2001b60c5a5748b0b7afd1c7ea1c84 Mon Sep 17 00:00:00 2001
From: Wojciech Sciesinski <it-praktyk@users.noreply.github.com>
Date: Tue, 5 Mar 2019 21:56:55 +0100
Subject: [PATCH] Extend win_psmodule - the second attempt, the previous was
 #46516 (#50621)

* Extend win_psmodule - rebased at 2019-01-07

* Change a way how defined parameters are added to the list

* Correct registering a repository

* Change way how tests for the check_mode: true are run

* Post-review updates

* Post-review updates -2

* Post-review updates -3

* Switch to PowerShell loop

* Minor updates

* Remove variants of an exception handling

* Change error handling
---
 lib/ansible/modules/windows/win_psmodule.ps1  | 506 ++++++++---
 lib/ansible/modules/windows/win_psmodule.py   | 101 ++-
 .../targets/win_psmodule/defaults/main.yml    |  22 +-
 .../targets/win_psmodule/meta/main.yml        |   2 +
 .../targets/win_psmodule/tasks/clean.yml      |  30 +
 .../targets/win_psmodule/tasks/main.yml       | 111 ++-
 .../targets/win_psmodule/tasks/tests.yml      | 808 ++++++++++++++++++
 .../tasks/{test.yml => tests_legacy.yml}      |  48 +-
 test/sanity/pslint/ignore.txt                 |   1 -
 9 files changed, 1442 insertions(+), 187 deletions(-)
 create mode 100644 test/integration/targets/win_psmodule/meta/main.yml
 create mode 100644 test/integration/targets/win_psmodule/tasks/clean.yml
 create mode 100644 test/integration/targets/win_psmodule/tasks/tests.yml
 rename test/integration/targets/win_psmodule/tasks/{test.yml => tests_legacy.yml} (81%)

diff --git a/lib/ansible/modules/windows/win_psmodule.ps1 b/lib/ansible/modules/windows/win_psmodule.ps1
index ac03580dfe2..1e7f058c247 100644
--- a/lib/ansible/modules/windows/win_psmodule.ps1
+++ b/lib/ansible/modules/windows/win_psmodule.ps1
@@ -1,65 +1,312 @@
 #!powershell
 
+# Copyright: (c) 2018, Wojciech Sciesinski <wojciech[at]sciesinski[dot]net>
 # Copyright: (c) 2017, Daniele Lazzari <lazzari@mailup.com>
 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
 
 #Requires -Module Ansible.ModuleUtils.Legacy
 
-# win_psmodule (Powershell modules Additions/Removal)
+# win_psmodule (Windows PowerShell modules Additions/Removals/Updates)
 
-$params = Parse-Args $args -supports_check_mode $true
+$params = Parse-Args -arguments $args -supports_check_mode $true
+$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
 
 $name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true
+$required_version = Get-AnsibleParam -obj $params -name "required_version" -type "str"
+$minimum_version = Get-AnsibleParam -obj $params -name "minimum_version" -type "str"
+$maximum_version = Get-AnsibleParam -obj $params -name "maximum_version" -type "str"
 $repo = Get-AnsibleParam -obj $params -name "repository" -type "str"
-$url = Get-AnsibleParam -obj $params -name "url" -type "str"
-$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present", "absent"
+$url = Get-AnsibleParam -obj $params -name "url" -type str
+$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "present", "absent", "latest"
 $allow_clobber = Get-AnsibleParam -obj $params -name "allow_clobber" -type "bool" -default $false
-$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false
+$skip_publisher_check = Get-AnsibleParam -obj $params -name "skip_publisher_check" -type "bool" -default $false
+$allow_prerelease = Get-AnsibleParam -obj $params -name "allow_prerelease" -type "bool" -default $false
 
-$result = @{"changed" = $false
-            "output" = ""
-            "nuget_changed" = $false
-            "repository_changed" = $false}
+$result = @{changed = $false
+            output = ""
+            nuget_changed = $false
+            repository_changed = $false}
 
 Function Install-NugetProvider {
-  param(
-    [bool]$CheckMode
+    Param(
+        [Bool]$CheckMode
     )
-  $PackageProvider = Get-PackageProvider -ListAvailable|?{($_.name -eq 'Nuget') -and ($_.version -ge "2.8.5.201")}
-  if (!($PackageProvider)){
-      try{
-        Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop -WhatIf:$CheckMode | out-null
-        $result.changed = $true
-        $result.nuget_changed = $true
-      }
-      catch{
-        $ErrorMessage = "Problems adding package provider: $($_.Exception.Message)"
-        Fail-Json $result $ErrorMessage
-      }
+    $PackageProvider = Get-PackageProvider -ListAvailable | Where-Object { ($_.name -eq 'Nuget') -and ($_.version -ge "2.8.5.201") }
+    if (-not($PackageProvider)){
+        try {
+            Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -WhatIf:$CheckMode | out-null
+            $result.changed = $true
+            $result.nuget_changed = $true
+        }
+        catch [ System.Exception ] {
+            $ErrorMessage = "Problems adding package provider: $($_.Exception.Message)"
+            Fail-Json $result $ErrorMessage
+        }
     }
 }
 
+Function Install-PrereqModule {
+    Param(
+        [Switch]$TestInstallationOnly,
+        [Bool]$CheckMode
+    )
+
+    # Those are minimum required versions of modules.
+    $PrereqModules = @{
+        PackageManagement = '1.1.7'
+        PowerShellGet = '1.6.0'
+    }
+
+    [Bool]$PrereqModulesInstalled = $true
+
+    ForEach ( $Name in $PrereqModules.Keys ) {
+
+        $ExistingPrereqModule = Get-Module -ListAvailable | Where-Object { ($_.name -eq $Name) -and ($_.version -ge $PrereqModules[$Name]) }
+
+        if ( -not $ExistingPrereqModule ) {
+            if ( $TestInstallationOnly ) {
+                $PrereqModulesInstalled = $false
+            }
+            else {
+                try {
+                    Install-Module -Name $Name -MinimumVersion $PrereqModules[$Name] -Force -WhatIf:$CheckMode | Out-Null
+
+                    if ( $Name -eq 'PowerShellGet' ) {
+                        # An order has to be reverted due to dependency
+                        Remove-Module -Name PowerShellGet, PackageManagement -Force
+                        Import-Module -Name PowerShellGet, PackageManagement -Force
+                    }
+
+                    $result.changed = $true
+                }
+                catch [ System.Exception ] {
+                    $ErrorMessage = "Problems adding a prerequisite module $Name $($_.Exception.Message)"
+                    Fail-Json $result $ErrorMessage
+                }
+            }
+        }
+    }
+
+    if ( $TestInstallationOnly ) {
+        $PrereqModulesInstalled
+    }
+}
+
+Function Get-PsModule {
+    Param(
+        [Parameter(Mandatory=$true)]
+        [String]$Name,
+        [String]$RequiredVersion,
+        [String]$MinimumVersion,
+        [String]$MaximumVersion
+    )
+
+    $ExistingModule = @{
+        Exists = $false
+        Version = ""
+    }
+
+    $ExistingModules = Get-Module -Listavailable | Where-Object {($_.name -eq $Name)}
+    $ExistingModulesCount = $($ExistingModules | Measure-Object).Count
+
+    if ( $ExistingModulesCount -gt 0 ) {
+
+        $ExistingModules | Add-Member -MemberType ScriptProperty -Name FullVersion -Value { if ( $null -ne ( $this.PrivateData ) ) { [String]"$($this.Version)-$(($this | Select-Object -ExpandProperty PrivateData).PSData.Prerelease)".TrimEnd('-') } else { [String]"$($this.Version)" } }
+
+        if ( -not ($RequiredVersion -or
+                $MinimumVersion -or
+                $MaximumVersion) )  {
+
+            $ReturnedModule = $ExistingModules | Select-Object -First 1
+        }
+        elseif ( $RequiredVersion ) {
+            $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $_.FullVersion -eq $RequiredVersion }
+        }
+        elseif ( $MinimumVersion -and $MaximumVersion ) {
+            $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MinimumVersion -le $_.Version -and $MaximumVersion -ge $_.Version } | Select-Object -First 1
+        }
+        elseif ( $MinimumVersion ) {
+            $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MinimumVersion -le $_.Version } | Select-Object -First 1
+        }
+        elseif ( $MaximumVersion ) {
+            $ReturnedModule = $ExistingModules | Where-Object -FilterScript { $MaximumVersion -ge $_.Version } | Select-Object -First 1
+        }
+    }
+
+    $ReturnedModuleCount = ($ReturnedModule | Measure-Object).Count
+
+    if ( $ReturnedModuleCount -eq 1 ) {
+        $ExistingModule.Exists = $true
+        $ExistingModule.Version = $ReturnedModule.FullVersion
+    }
+
+    $ExistingModule
+}
+
+Function Add-DefinedParameter {
+    Param (
+        [Parameter(Mandatory=$true)]
+        [Hashtable]$Hashtable,
+        [Parameter(Mandatory=$true)]
+        [String[]]$ParametersNames
+    )
+
+    ForEach ($ParameterName in $ParametersNames) {
+        $ParameterVariable = Get-Variable -Name $ParameterName -ErrorAction Ignore
+        if ( $ParameterVariable.Value -and $Hashtable.Keys -notcontains $ParameterName ){
+                $Hashtable.Add($ParameterName,$ParameterVariable.Value)
+        }
+    }
+
+    $Hashtable
+}
+
+Function Install-PsModule {
+    Param(
+        [Parameter(Mandatory=$true)]
+        [String]$Name,
+        [String]$RequiredVersion,
+        [String]$MinimumVersion,
+        [String]$MaximumVersion,
+        [String]$Repository,
+        [Bool]$AllowClobber,
+        [Bool]$SkipPublisherCheck,
+        [Bool]$AllowPrerelease,
+        [Bool]$CheckMode
+    )
+
+    $ExistingModuleBefore = Get-PsModule -Name $Name -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion
+
+    if ( -not $ExistingModuleBefore.Exists ) {
+        try {
+            # Install NuGet provider if needed.
+            Install-NugetProvider -CheckMode $CheckMode
+
+            $ht = @{
+                Name = $Name
+                WhatIf = $CheckMode
+                Force = $true
+            }
+
+            [String[]]$ParametersNames = @("RequiredVersion","MinimumVersion","MaximumVersion","AllowPrerelease","AllowClobber","SkipPublisherCheck","Repository")
+
+            $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames
+
+            Install-Module @ht -ErrorVariable ErrorDetails | out-null
+
+            $result.changed = $true
+            $result.output = "Module $($Name) installed"
+        }
+        catch [ System.Exception ] {
+            $ErrorMessage = "Problems installing $($Name) module: $($_.Exception.Message)"
+            Fail-Json $result $ErrorMessage
+        }
+    }
+    else {
+        $result.output = "Module $($Name) already present"
+    }
+}
+
+Function Remove-PsModule {
+    Param(
+        [Parameter(Mandatory=$true)]
+        [String]$Name,
+        [String]$RequiredVersion,
+        [String]$MinimumVersion,
+        [String]$MaximumVersion,
+        [Bool]$CheckMode
+    )
+    # If module is present, uninstalls it.
+    if (Get-Module -Listavailable | Where-Object {$_.name -eq $Name}) {
+        try {
+            $ht = @{
+                Name = $Name
+                Confirm = $false
+                Force = $true
+            }
+
+            $ExistingModuleBefore = Get-PsModule -Name $Name -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion
+
+            [String[]]$ParametersNames = @("RequiredVersion","MinimumVersion","MaximumVersion")
+
+            $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames
+
+            if ( -not ( $RequiredVersion -or $MinimumVersion -or $MaximumVersion ) ) {
+                $ht.Add("AllVersions", $true)
+            }
+
+            if ( $ExistingModuleBefore.Exists) {
+                # The Force parameter overwrite the WhatIf parameter
+                if ( -not $CheckMode ) {
+                    Uninstall-Module @ht -ErrorVariable ErrorDetails | out-null
+                }
+                $result.changed = $true
+                $result.output = "Module $($Name) removed"
+            }
+        }
+        catch [ System.Exception ] {
+            $ErrorMessage = "Problems uninstalling $($Name) module: $($_.Exception.Message)"
+            Fail-Json $result $ErrorMessage
+        }
+    }
+    else {
+        $result.output = "Module $($Name) removed"
+    }
+}
+
+Function Find-LatestPsModule {
+    Param(
+        [Parameter(Mandatory=$true)]
+        [String]$Name,
+        [String]$Repository,
+        [Bool]$AllowPrerelease,
+        [Bool]$CheckMode
+    )
+
+    try {
+        $ht = @{
+            Name = $Name
+        }
+
+        [String[]]$ParametersNames = @("AllowPrerelease","Repository")
+
+        $ht = Add-DefinedParameter -Hashtable $ht -ParametersNames $ParametersNames
+
+        $LatestModule = Find-Module @ht
+        $LatestModuleVersion = $LatestModule.Version
+    }
+    catch [ System.Exception ] {
+        $ErrorMessage = "Cant find the module $($Name): $($_.Exception.Message)"
+        Fail-Json $result $ErrorMessage
+    }
+
+    $LatestModuleVersion
+}
+
 Function Install-Repository {
     Param(
-    [Parameter(Mandatory=$true)]
-    [string]$Name,
-    [Parameter(Mandatory=$true)]
-    [string]$Url,
-    [bool]$CheckMode
+        [Parameter(Mandatory=$true)]
+        [string]$Name,
+        [Parameter(Mandatory=$true)]
+        [string]$Url,
+        [bool]$CheckMode
     )
-    $Repo = (Get-PSRepository).SourceLocation
+    # Install NuGet provider if needed.
+    Install-NugetProvider -CheckMode $CheckMode
+
+    $Repos = (Get-PSRepository).SourceLocation
 
     # If repository isn't already present, try to register it as trusted.
-    if ($Repo -notcontains $Url){ 
+    if ($Repos -notcontains $Url){
       try {
-           if (!($CheckMode)) {
-               Register-PSRepository -Name $Name -SourceLocation $Url -InstallationPolicy Trusted -ErrorAction Stop       
+           if ( -not ($CheckMode) ) {
+               Register-PSRepository -Name $Name -SourceLocation $Url -InstallationPolicy Trusted -ErrorAction Stop
            }
           $result.changed = $true
           $result.repository_changed = $true
       }
       catch {
-        $ErrorMessage = "Problems adding $($Name) repository: $($_.Exception.Message)"
+        $ErrorMessage = "Problems registering $($Name) repository: $($_.Exception.Message)"
         Fail-Json $result $ErrorMessage
       }
     }
@@ -67,120 +314,143 @@ Function Install-Repository {
 
 Function Remove-Repository{
     Param(
-    [Parameter(Mandatory=$true)]
-    [string]$Name,
-    [bool]$CheckMode
+        [Parameter(Mandatory=$true)]
+        [string]$Name,
+        [bool]$CheckMode
     )
 
-    $Repo = (Get-PSRepository).SourceLocation
+    $Repo = (Get-PSRepository).Name
 
     # Try to remove the repository
     if ($Repo -contains $Name){
-        try {         
-            if (!($CheckMode)) {
+        try {
+            if ( -not ($CheckMode) ) {
                 Unregister-PSRepository -Name $Name -ErrorAction Stop
             }
             $result.changed = $true
             $result.repository_changed = $true
         }
-        catch {
-            $ErrorMessage = "Problems removing $($Name)repository: $($_.Exception.Message)"
+        catch [ System.Exception ] {
+            $ErrorMessage = "Problems unregistering $($Name)repository: $($_.Exception.Message)"
             Fail-Json $result $ErrorMessage
         }
     }
 }
 
-Function Install-PsModule {
-    param(
-      [Parameter(Mandatory=$true)]
-      [string]$Name,
-      [string]$Repository,
-      [bool]$AllowClobber,
-      [bool]$CheckMode
-    )
-    if (Get-Module -Listavailable|?{$_.name -eq $Name}){
-        $result.output = "Module $($Name) already present"
-    }
-    else {      
-      try{
-        # Install NuGet Provider if needed
-        Install-NugetProvider -CheckMode $CheckMode;
-
-        $ht = @{
-            Name      = $Name;
-            WhatIf    = $CheckMode;
-            ErrorAction = "Stop";
-            Force     = $true;
-        };
-
-        # If specified, use repository name to select module source
-        if ($Repository) {
-            $ht["Repository"] = "$Repository";
-        }
-
-        # Check Powershell Version (-AllowClobber was introduced in PowerShellGet 1.6.0)
-        if ("AllowClobber" -in ((Get-Command PowerShellGet\Install-Module | Select -ExpandProperty Parameters).Keys)) {
-          $ht['AllowClobber'] = $AllowClobber;
-        }
-        
-        Install-Module @ht | out-null;
-        
-        $result.output = "Module $($Name) installed"
-        $result.changed = $true
-      }
-      catch{
-        $ErrorMessage = "Problems installing $($Name) module: $($_.Exception.Message)"
-        Fail-Json $result $ErrorMessage
-      }
-    }
-}
-
-Function Remove-PsModule {
-    param(
-      [Parameter(Mandatory=$true)]
-      [string]$Name,
-      [bool]$CheckMode
-    )
-    # If module is present, unistalls it.
-    if (Get-Module -Listavailable|?{$_.name -eq $Name}){
-      try{
-        Uninstall-Module -Name $Name -Confirm:$false -Force -ErrorAction Stop -WhatIf:$CheckMode | out-null
-        $result.output = "Module $($Name) removed"
-        $result.changed = $true
-      }
-      catch{
-        $ErrorMessage = "Problems removing $($Name) module: $($_.Exception.Message)"
-        Fail-Json $result $ErrorMessage
-      }
-
-    }
-    else{
-      $result.output = "Module $($Name) not present"
-    }
-}
-
-# Check powershell version, fail if < 5.0
+# Check PowerShell version, fail if < 5.0 and required modules are not installed
 $PsVersion = $PSVersionTable.PSVersion
-if ($PsVersion.Major -lt 5){
-  $ErrorMessage = "Powershell 5.0 or higher is needed"
-  Fail-Json $result $ErrorMessage
+if ($PsVersion.Major -lt 5 ) {
+    $PrereqModulesInstalled = Install-PrereqModule -TestInstallationOnly
+    if ( -not $PrereqModulesInstalled ) {
+        $ErrorMessage = "Modules PowerShellGet and PackageManagement in versions 1.6.0 and 1.1.7 respectively have to be installed before using the win_psmodule."
+        Fail-Json $result $ErrorMessage
+    }
 }
 
+if ( $required_version -and ( $minimum_version -or $maximum_version ) ) {
+       $ErrorMessage = "Parameters required_version and minimum/maximum_version are mutually exclusive."
+       Fail-Json $result $ErrorMessage
+}
+
+if ( $allow_prerelease -and ( $minimum_version -or $maximum_version ) ) {
+    $ErrorMessage = "Parameters minimum_version, maximum_version can't be used with the parameter allow_prerelease."
+    Fail-Json $result $ErrorMessage
+}
+
+if ( $allow_prerelease -and $state -eq "absent" ) {
+    $ErrorMessage = "The parameter allow_prerelease can't be used with state set to 'absent'."
+    Fail-Json $result $ErrorMessage
+}
+
+if ( ($state -eq "latest") -and
+    ( $required_version -or $minimum_version -or $maximum_version ) ) {
+        $ErrorMessage = "When the parameter state is equal 'latest' you can use any of required_version, minimum_version, maximum_version."
+        Fail-Json $result $ErrorMessage
+}
+
+if ( $repo -and (-not $url) ) {
+    $RepositoryExists = Get-PSRepository -Name $repo -ErrorAction Ignore
+    if ( $null -eq $RepositoryExists) {
+        $ErrorMessage = "The repository $repo doesn't exist."
+        Fail-Json $result $ErrorMessage
+    }
+
+}
+
+if ( ($allow_clobber -or $allow_prerelease -or $skip_publisher_check -or
+    $required_version -or $minimum_version -or $maximum_version) ) {
+    # Update the PowerShellGet and PackageManagement modules.
+    # It's required to support AllowClobber, AllowPrerelease parameters.
+    Install-PrereqModule -CheckMode $check_mode
+}
+
+Import-Module -Name PackageManagement, PowerShellGet
+
 if ($state -eq "present") {
     if (($repo) -and ($url)) {
-        Install-Repository -Name $repo -Url $url -CheckMode $check_mode 
+        Install-Repository -Name $repo -Url $url -CheckMode $check_mode
     }
     else {
         $ErrorMessage = "Repository Name and Url are mandatory if you want to add a new repository"
     }
 
-    Install-PsModule -Name $Name -Repository $repo -CheckMode $check_mode -AllowClobber $allow_clobber;
+    if ($name) {
+        $ht = @{
+            Name = $name
+            RequiredVersion = $required_version
+            MinimumVersion = $minimum_version
+            MaximumVersion = $maximum_version
+            Repository = $repo
+            AllowClobber = $allow_clobber
+            SkipPublisherCheck = $skip_publisher_check
+            AllowPrerelease = $allow_prerelease
+            CheckMode = $check_mode
+        }
+        Install-PsModule @ht
+    }
 }
-else {  
-    if ($repo) {   
+elseif ($state -eq "absent") {
+    if ($repo) {
         Remove-Repository -Name $repo -CheckMode $check_mode
     }
-    Remove-PsModule -Name $Name -CheckMode $check_mode
+
+    if ($name) {
+        $ht = @{
+            Name = $Name
+            CheckMode = $check_mode
+            RequiredVersion = $required_version
+            MinimumVersion = $minimum_version
+            MaximumVersion = $maximum_version
+        }
+        Remove-PsModule @ht
+    }
+}
+elseif ( $state -eq "latest") {
+
+    $ht = @{
+        Name = $Name
+        AllowPrerelease = $allow_prerelease
+        Repository = $repo
+        CheckMode = $check_mode
+    }
+
+    $LatestVersion = Find-LatestPsModule @ht
+
+    $ExistingModule = Get-PsModule $Name
+
+    if ( $LatestVersion.Version -ne $ExistingModule.Version ) {
+
+        $ht = @{
+            Name = $Name
+            RequiredVersion = $LatestVersion
+            Repository = $repo
+            AllowClobber = $allow_clobber
+            SkipPublisherCheck = $skip_publisher_check
+            AllowPrerelease = $allow_prerelease
+            CheckMode = $check_mode
+        }
+        Install-PsModule @ht
+    }
 }
 
 Exit-Json $result
diff --git a/lib/ansible/modules/windows/win_psmodule.py b/lib/ansible/modules/windows/win_psmodule.py
index cbdc4093886..21312cbcb4d 100644
--- a/lib/ansible/modules/windows/win_psmodule.py
+++ b/lib/ansible/modules/windows/win_psmodule.py
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 
+# Copyright: (c) 2018, Wojciech Sciesinski <wojciech[at]sciesinski[dot]net>
 # Copyright: (c) 2017, Daniele Lazzari <lazzari@mailup.com>
 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
 
@@ -15,20 +16,58 @@ DOCUMENTATION = r'''
 ---
 module: win_psmodule
 version_added: "2.4"
-short_description: Adds or removes a Powershell Module
+short_description: Adds or removes a Windows PowerShell module
 description:
-    - This module helps to install Powershell modules and register custom modules repository on Windows Server.
+  - This module helps to install Windows PowerShell modules and register custom modules repository on Windows-based systems.
 options:
   name:
     description:
-      - Name of the powershell module that has to be installed.
+      - Name of the Windows PowerShell module that has to be installed.
     type: str
     required: yes
+  state:
+    description:
+      - If C(present) a new module is installed.
+      - If C(absent) a module is removed.
+      - If C(latest) a module is updated to the newest version. This option was added in version 2.8.
+    type: str
+    choices: [ absent, latest, present ]
+    default: present
+  required_version:
+    description:
+      - The exact version of the PowerShell module that has to be installed.
+    type: str
+    version_added: "2.8"
+  minimum_version:
+    description:
+      - The minimum version of the PowerShell module that has to be installed.
+    type: str
+    version_added: "2.8"
+  maximum_version:
+    description:
+      - The maximum version of the PowerShell module that has to be installed.
+    type: str
+    version_added: "2.8"
   allow_clobber:
     description:
-      - If C(yes) imports all commands, even if they have the same names as commands that already exists. Available only in Powershell 5.1 or higher.
+      - If C(yes) allows install modules that contains commands those have the same names as commands that already exists.
     type: bool
     default: no
+  skip_publisher_check:
+    description:
+      - If C(yes), allows you to install a different version of a module that already exists on your computer in the case when a different one
+        is not digitally signed by a trusted publisher and the newest existing module is digitally signed by a trusted publisher.
+    type: bool
+    default: no
+    version_added: "2.8"
+  allow_prerelease:
+    description:
+      - If C(yes) installs modules marked as prereleases.
+      - It doesn't work with the parameters C(minimum_version) and/or C(maximum_version).
+      - It doesn't work with the C(state) set to absent.
+    type: bool
+    default: no
+    version_added: "2.8"
   repository:
     description:
       - Name of the custom repository to register or use.
@@ -37,50 +76,60 @@ options:
     description:
       - URL of the custom repository to register.
     type: str
-  state:
-    description:
-      - If C(present) a new module is installed.
-      - If C(absent) a module is removed.
-    type: str
-    choices: [ absent, present ]
-    default: present
 notes:
-   -  Powershell 5.0 or higher is needed.
+  - PowerShell modules needed
+      - PowerShellGet >= 1.6.0
+      - PackageManagement >= 1.1.7
+  - PowerShell package provider needed
+      - NuGet >= 2.8.5.201
+  - On PowerShell 5.x required modules and a package provider will be updated under the first run of the win_psmodule module.
+  - On PowerShell 3.x and 4.x you have to install them before using the win_psmodule.
 seealso:
 - module: win_psrepository
 author:
+- Wojciech Sciesinski (@it-praktyk)
 - Daniele Lazzari (@dlazz)
 '''
 
 EXAMPLES = r'''
 ---
-- name: Add a powershell module
+- name: Add a PowerShell module
   win_psmodule:
-    name: PowershellModule
+    name: PowerShellModule
     state: present
 
-- name: Add a powershell module and register a repository
+- name: Add an exact version of PowerShell module
+  win_psmodule:
+    name: PowerShellModule
+    required_version: "4.0.2"
+    state: present
+
+- name: Install or update an existing PowerShell module to the newest version
+  win_psmodule:
+    name: PowerShellModule
+    state: latest
+
+- name: Install newer version of built-in Windows module
+  win_psmodule:
+    name: Pester
+    skip_publisher_check: yes
+    state: present
+
+- name: Add a PowerShell module and register a repository
   win_psmodule:
     name: MyCustomModule
     repository: MyRepository
-    url: https://myrepo.com
     state: present
 
-- name: Add a powershell module from a specific repository
+- name: Add a PowerShell module from a specific repository
   win_psmodule:
-    name: PowershellModule
+    name: PowerShellModule
     repository: MyRepository
     state: present
 
-- name: Remove a powershell module
+- name: Remove a PowerShell module
   win_psmodule:
-    name: PowershellModule
-    state: absent
-
-- name: Remove a powershell module and a repository
-  win_psmodule:
-    name: MyCustomModule
-    repository: MyRepository
+    name: PowerShellModule
     state: absent
 '''
 
diff --git a/test/integration/targets/win_psmodule/defaults/main.yml b/test/integration/targets/win_psmodule/defaults/main.yml
index fbfdf97cce7..9c89b53b254 100644
--- a/test/integration/targets/win_psmodule/defaults/main.yml
+++ b/test/integration/targets/win_psmodule/defaults/main.yml
@@ -1,7 +1,27 @@
 ---
-
 powershell_module: powershell-yaml
 wrong_module: powershell_yaml
 allow_clobber_module: PowerShellCookbook
+fake_repo_name: FakeRepo
 custom_repo_path: C:\_repo
 custom_repo_name: PSRegisterRepo
+
+powershell_module_required_version: 0.3.4
+powershell_module_maximum_version_request: 0.2.2
+powershell_module_maximum_version_result: 0.2
+powershell_module_ultra_high_version: 15.0.0
+powershell_module_ultra_low_version: 0.0.1
+
+skip_publisher_check_module: Pester
+
+powershell_module_2: Pester
+powershell_module_2_minimum_version_request: 3.1.2
+powershell_module_2_maximum_version_request: 3.3.0
+powershell_module_2_minimum_maximum_version_result: 3.2.0
+
+allow_prerelease_module: Pester
+allow_prerelease_version: 4.4.0-beta2
+
+myget_powershell_module: xActiveDirectory
+myget_repository_name: My Get
+myget_repository_url: https://www.myget.org/F/powershellgetdemo/api/v2
diff --git a/test/integration/targets/win_psmodule/meta/main.yml b/test/integration/targets/win_psmodule/meta/main.yml
new file mode 100644
index 00000000000..bdea853d75a
--- /dev/null
+++ b/test/integration/targets/win_psmodule/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+- prepare_win_tests
diff --git a/test/integration/targets/win_psmodule/tasks/clean.yml b/test/integration/targets/win_psmodule/tasks/clean.yml
new file mode 100644
index 00000000000..c56d751b6b0
--- /dev/null
+++ b/test/integration/targets/win_psmodule/tasks/clean.yml
@@ -0,0 +1,30 @@
+# This file is part of Ansible
+
+# test code for the win_psmodule module when using winrm connection
+# Copyright: (c) 2018, Wojciech Sciesinski <wojciech[at]sciesinski[dot]net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+---
+- name: uninstall any versions of modules used for tests
+  win_shell: |
+    $ModulesToUninstall = @('powershell-yaml', 'Pester', 'PowerShellCookbook', 'xActiveDirectory')
+    ForEach ( $ModuleToUninstall in $ModulesToUninstall ) {
+      Uninstall-Module $ModuleToUninstall -AllVersions -Force -ErrorAction Ignore
+    }
+  changed_when: false
+
+- name: unregister the custom repo
+  win_psrepository:
+    name: "{{ item | quote }}"
+    state: absent
+  changed_when: false
+  with_items:
+    - "{{ custom_repo_name }}"
+    - "{{ myget_repository_name }}"
+
+- name: remove the custom repo folder
+  win_file:
+    path: "{{ custom_repo_path }}"
+    state: absent
+  changed_when: false
+  ignore_errors: yes
diff --git a/test/integration/targets/win_psmodule/tasks/main.yml b/test/integration/targets/win_psmodule/tasks/main.yml
index 7daa4685503..cbac2c9f92a 100644
--- a/test/integration/targets/win_psmodule/tasks/main.yml
+++ b/test/integration/targets/win_psmodule/tasks/main.yml
@@ -1,28 +1,95 @@
-# test code for the win_psmodule module when using winrm connection
-# (c) 2017, Daniele Lazzari <lazzari@mailup.com>
-
 # This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
 
+# test code for the win_psmodule module when using winrm connection
+# Copyright: (c) 2018, Wojciech Sciesinski <wojciech[at]sciesinski[dot]net>
+# Copyright: (c) 2017, Daniele Lazzari <lazzari@mailup.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
 
-- name: get facts
-  setup:
+- name: get PowerShell version
+  win_shell: '$PSVersionTable.PSVersion.Major'
+  changed_when: false
+  register: powershell_major_version
 
-- name: Perform integration tests for Powershell 5+
-  when: ansible_powershell_version >= 5
+- name: update PackageManagement and PowerShellGet when PowerShell < 5.0
+  when: powershell_major_version.stdout | int < 5
   block:
+    - name: download PackageManagement
+      win_get_url:
+        url: https://s3.amazonaws.com/ansible-ci-files/test/integration/targets/win_psmodule/PackageManagement_x64.msi
+        dest: '{{ win_output_dir }}\PackageManagement_x64.msi'
 
-    - name: run all tasks
-      include: test.yml
+    - name: install PackageManagement
+      win_package:
+        path: '{{ win_output_dir }}\PackageManagement_x64.msi'
+        state: present
+
+    - name: create the required folder
+      win_file:
+        path: 'C:\Program Files\PackageManagement\ProviderAssemblies'
+        state: directory
+
+    - name: download nuget
+      win_get_url:
+        url: https://s3.amazonaws.com/ansible-ci-files/test/integration/targets/win_psmodule/nuget.exe
+        dest: 'C:\Program Files\PackageManagement\ProviderAssemblies\NuGet-anycpu.exe'
+
+    - name: update NuGet provider
+      win_shell: 'Find-PackageProvider -Name Nuget -ForceBootstrap -IncludeDependencies'
+
+    - name: download and save the nevest version of the PackageManagement module from PowerShell Gallery
+      win_shell: 'Save-Module -Name PackageManagement, PowerShellGet -Path {{ win_output_dir }} -Force'
+
+    - name: unload PackageManagement and PowerShellGet modules
+      win_shell: 'Remove-Module -Name PackageManagement,PowerShellGet -Force -ErrorAction Ignore'
+      ignore_errors: yes
+
+    - name: get PSModulePath
+      win_shell: "$($Env:PSModulePath -Split ';')[0]"
+      register: psmodulepath
+
+    - name: remove older versions of the PackageManagement and PowerShellGet
+      win_file:
+        path: "{{ psmodulepath.stdout | trim }}\\{{ item }}"
+        state: absent
+      with_items:
+        - PackageManagement
+        - PowerShellGet
+
+    - name: create required folder
+      win_file:
+        path:  "{{ psmodulepath.stdout | trim }}"
+        state: directory
+
+    - name: update PowerShellGet and PackageManagement modules
+      win_shell: 'Copy-Item -Path {{ win_output_dir }}\{{ item }} -Destination {{ psmodulepath.stdout | trim }}\ -Recurse -Force'
+      with_items:
+        - PackageManagement
+        - PowerShellGet
+
+- name: update NuGet version
+  when: powershell_major_version.stdout | int >= 5
+  win_shell: |
+    $nuget_exists = (Get-PackageProvider | Where-Object { $_.Name -eq 'Nuget' } | Measure-Object).Count -eq 1
+
+    if ( $nuget_exists ) {
+      $nuget_outdated = (Get-PackageProvider -Name NuGet -ErrorAction Ignore).Version -lt [Version]"2.8.5.201"
+    }
+
+    if ( -not $nuget_exists -or $nuget_outdated ) {
+      Find-PackageProvider -Name Nuget -ForceBootstrap -IncludeDependencies -Force
+    }
+
+- name: perform cleanup before tests run
+  include: clean.yml
+
+- name: run tests
+  include: tests.yml
+
+- name: peform legacy (backward compatibility) tests
+  when: powershell_major_version.stdout | int == 5
+  block:
+    - name: perform cleanup before legacy tests run
+      include: clean.yml
+
+    - name: run legacy tests
+      include: tests_legacy.yml
diff --git a/test/integration/targets/win_psmodule/tasks/tests.yml b/test/integration/targets/win_psmodule/tasks/tests.yml
new file mode 100644
index 00000000000..63370ad04cc
--- /dev/null
+++ b/test/integration/targets/win_psmodule/tasks/tests.yml
@@ -0,0 +1,808 @@
+# This file is part of Ansible
+
+# test code for the win_psmodule module when using winrm connection
+# Copyright: (c) 2018, Wojciech Sciesinski <wojciech[at]sciesinski[dot]net>
+# Copyright: (c) 2017, Daniele Lazzari <lazzari@mailup.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+---
+
+- name: "get the latest version of the {{ powershell_module }} module in PowerShell Gallery"
+  win_shell: "((Find-Module -Name {{ powershell_module }}).Version).ToString()"
+  changed_when: false
+  register: module_latest_version
+
+- name: "get {{ skip_publisher_check_module }} is preinstalled"
+  win_shell: "(Get-Module -Name {{ skip_publisher_check_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count"
+  register: skip_publisher_module_exist
+
+- name: "check installing module from Powershell Gallery - without version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    state: present
+  check_mode: yes
+  register: module_without_version_setup_1
+
+- name: get result installing module from Powershell Gallery - without version
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ module_latest_version.stdout | trim }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_without_version_setup_1
+
+- name: "test installing module from Powershell Gallery - without version - check mode: true"
+  assert:
+    that:
+      - module_without_version_setup_1 is changed
+      - result_module_without_version_setup_1.stdout | trim | bool == false
+
+- name: "check installing module from Powershell Gallery - without version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    state: present
+  register: module_without_version_setup_1
+
+- name: "get result installing module from Powershell Gallery - without version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ module_latest_version.stdout | trim }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_without_version_setup_1
+
+- name: "test installing module from Powershell Gallery - without version - check mode: false"
+  assert:
+    that:
+      - module_without_version_setup_1 is changed
+      - result_module_without_version_setup_1.stdout | trim | bool == true
+
+- name: check idempotency installing module from PowerShell Gallery - without version
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    state: present
+  register: module_without_version_setup_2
+
+- name: test idempotency installing module from PowerShell Gallery - without version
+  assert:
+    that:
+      - module_without_version_setup_2 is not changed
+
+- name: "check uninstalling PowerShell module - without version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    state: absent
+  check_mode: yes
+  register: module_uninstall_without_version
+
+- name: "get result uninstalling PowerShell module - without version - check mode: true"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable | Measure-Object ).Count -ge 1"
+  changed_when: false
+  register: result_module_uninstall_without_version
+
+- name: "test uninstalling PowerShell module - without version - check mode: true"
+  assert:
+    that:
+      - module_uninstall_without_version is changed
+      - result_module_uninstall_without_version.stdout | trim | bool == true
+
+- name: "check uninstalling PowerShell module - without version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    state: absent
+  register: module_uninstall_without_version
+
+- name: "get result uninstalling PowerShell module - without version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable | Measure-Object ).Count -eq 0"
+  changed_when: false
+  register: result_module_uninstall_without_version
+
+- name: "test uninstalling PowerShell module - without version - check mode: false"
+  assert:
+    that:
+      - module_uninstall_without_version is changed
+      - result_module_uninstall_without_version.stdout | trim | bool == true
+
+- name: check idempotency uninstalling PowerShell module - without version
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    state: absent
+  register: module_uninstall_2
+
+- name: test idempotency uninstalling PowerShell module - without version
+  assert:
+    that:
+      - module_uninstall_2 is not changed
+
+- name: "check installing module from Powershell Gallery - required_version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    required_version: "{{ powershell_module_required_version }}"
+    state: present
+  check_mode: yes
+  register: module_required_version_setup_1
+
+- name: "get result installing module from Powershell Gallery - required_version - check mode: true"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_required_version_setup_1
+
+- name: "test installing module from Powershell Gallery - required_version - check mode: true"
+  assert:
+    that:
+      - module_required_version_setup_1 is changed
+      - result_module_required_version_setup_1.stdout | trim | bool == false
+
+- name: "check installing module from Powershell Gallery - required_version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    required_version: "{{ powershell_module_required_version }}"
+    state: present
+  register: module_required_version_setup_1
+
+- name: "get result installing module from Powershell Gallery - required_version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_required_version_setup_1
+
+- name: "test installing module from Powershell Gallery - required_version - check mode: false"
+  assert:
+    that:
+      - module_required_version_setup_1 is changed
+      - result_module_required_version_setup_1.stdout | trim | bool == true
+
+- name: check idempotency installing module from Powershell Gallery - required_version
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    required_version: "{{ powershell_module_required_version }}"
+    state: present
+  register: module_required_version_setup_2
+
+- name: test idempotency installing module from Powershell Gallery - required_version
+  assert:
+    that:
+      - module_required_version_setup_2 is not changed
+
+- name: "check uninstall PowerShell module - required_version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    required_version: "{{ powershell_module_required_version }}"
+    state: absent
+  register: module_uninstall_required_version
+
+- name: "get result uninstall PowerShell module - required_version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 0"
+  changed_when: false
+  register: result_module_uninstall_required_version
+
+- name: "test PowerShell module uninstall - required_version - check mode: false"
+  assert:
+    that:
+      - module_uninstall_required_version is changed
+      - result_module_uninstall_required_version.stdout | trim | bool == true
+
+- name: check installing module from Powershell Gallery - required_version but not existing
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    required_version: "{{ powershell_module_ultra_high_version }}"
+    state: present
+  register: module_required_version_setup_3
+  ignore_errors: yes
+
+- name: test installing module from Powershell Gallery - required_version but not existing
+  assert:
+    that:
+      - module_required_version_setup_3 is not changed
+      - module_required_version_setup_3 is failed
+      - "'Problems installing {{ powershell_module }} module: No match was found for the specified search criteria' in module_required_version_setup_3.msg"
+
+- name: "check installing module from Powershell Gallery - maximum_version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    maximum_version: "{{ powershell_module_maximum_version_request }}"
+    state: present
+  check_mode: yes
+  register: module_maximum_version_setup_1
+
+- name: "get result installing module from Powershell Gallery - maximum_version - check mode: true"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_maximum_version_setup_1
+
+- name: "test installing module from Powershell Gallery - maximum_version - check mode: true"
+  assert:
+    that:
+      - module_maximum_version_setup_1 is changed
+      - result_module_maximum_version_setup_1.stdout | trim | bool == false
+
+- name: "check installing module from Powershell Gallery - maximum_version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    maximum_version: "{{ powershell_module_maximum_version_request }}"
+    state: present
+  register: module_maximum_version_setup_1
+
+- name: "get result installing module from Powershell Gallery - maximum_version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_maximum_version_setup_1
+
+- name: "test installing module from Powershell Gallery - maximum_version - check mode: false"
+  assert:
+    that:
+      - module_maximum_version_setup_1 is changed
+      - result_module_maximum_version_setup_1.stdout | trim | bool == true
+
+- name: check idempotency installing module from Powershell Gallery - maximum_version
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    maximum_version: "{{ powershell_module_maximum_version_request }}"
+    state: present
+  register: module_maximum_version_setup_2
+
+- name: test idempotency installing module from Powershell Gallery - maximum_version
+  assert:
+    that:
+      - module_maximum_version_setup_2 is not changed
+
+- name: "check uninstall PowerShell module - maximum_version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    maximum_version: "{{ powershell_module_maximum_version_request }}"
+    state: absent
+  check_mode: yes
+  register: module_uninstall_maximum_version
+
+- name: "get result uninstall PowerShell module - maximum_version - check mode: true"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_uninstall_maximum_version
+
+- name: "test PowerShell module uninstall - maximum_version - check mode: true"
+  assert:
+    that:
+      - module_uninstall_maximum_version is changed
+      - result_module_uninstall_maximum_version.stdout | trim | bool == true
+
+- name: "check uninstall PowerShell module - maximum_version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    maximum_version: "{{ powershell_module_maximum_version_request }}"
+    state: absent
+  register: module_uninstall_maximum_version
+
+- name: "get result uninstall PowerShell module - maximum_version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_maximum_version_result }}' } | Measure-Object).Count -eq 0"
+  changed_when: false
+  register: result_module_uninstall_maximum_version
+
+- name: "test PowerShell module uninstall - maximum_version - check mode: false"
+  assert:
+    that:
+      - module_uninstall_maximum_version is changed
+      - result_module_uninstall_maximum_version.stdout | trim | bool == true
+
+- name: check installing module from Powershell Gallery - maximum_version but not existing
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    maximum_version: "{{ powershell_module_ultra_low_version }}"
+    state: present
+  register: module_maximum_version_setup_3
+  ignore_errors: yes
+
+- name: test installing module from Powershell Gallery - maximum_version but not existing
+  assert:
+    that:
+      - module_maximum_version_setup_3 is not changed
+      - module_maximum_version_setup_3 is failed
+
+  # Don't move skip_publisher_check tests below minimum_version and maximum_version tests
+- name: check installing module with skip_publisher_check not active
+  win_psmodule:
+    name: "{{ skip_publisher_check_module }}"
+    # Adding a required version is required because the tested module
+    # is bundled within OS and has not be digitally signed (since 4.4.3 it's)
+    required_version: "4.2.0"
+  # Run only for systems with built'in module e.g. Windows 10
+  when: skip_publisher_module_exist.stdout | int == 1
+  register: fail_skip_publisher_check
+  ignore_errors: yes
+
+- name: test installing module with skip_publisher_check not active
+  assert:
+    that:
+      - fail_skip_publisher_check is failed
+      - "'being installed is not catalog signed. Ensure that the version' in fail_skip_publisher_check.msg"
+  when: skip_publisher_module_exist.stdout | int >= 1
+
+- name: "check installing module with skip_publisher_check active - check mode: true"
+  win_psmodule:
+    name: "{{ skip_publisher_check_module }}"
+    # Adding a required version is required because the tested module
+    # is bundled within OS and has not be digitally signed (since 4.4.3 it's)
+    required_version: "4.2.0"
+    skip_publisher_check: yes
+  check_mode: yes
+  register: ok_skip_publisher_check
+
+- name: "get result installing module with skip_publisher_check active - check mode: true"
+  win_shell: "(Get-Module -Name {{ skip_publisher_check_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq {{ skip_publisher_module_exist.stdout | int }}"
+  changed_when: false
+  register: result_ok_skip_publisher_check
+
+- name: "test installing module with skip_publisher_check active - check mode: true"
+  assert:
+    that:
+      - ok_skip_publisher_check is changed
+      - result_ok_skip_publisher_check.stdout | trim | bool == true
+
+- name: "check installing module with skip_publisher_check active - check mode: false"
+  win_psmodule:
+    name: "{{ skip_publisher_check_module }}"
+    # Adding a required version is required because the tested module
+    # is bundled within OS and has not be digitally signed (since 4.4.3 it's)
+    required_version: "4.2.0"
+    skip_publisher_check: yes
+  register: ok_skip_publisher_check
+
+- name: "get result installing module with skip_publisher_check active - check mode: false"
+  win_shell: "(Get-Module -Name {{ skip_publisher_check_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq {{ skip_publisher_module_exist.stdout | int + 1 }}"
+  changed_when: false
+  register: result_ok_skip_publisher_check
+
+- name: "test installing module with skip_publisher_check active - check mode: false"
+  assert:
+    that:
+      - ok_skip_publisher_check is changed
+      - result_ok_skip_publisher_check.stdout | trim | bool == true
+
+- name: "check Powershell Gallery module setup - minimum_version and maximum_version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module_2 }}"
+    minimum_version: "{{ powershell_module_2_minimum_version_request }}"
+    maximum_version: "{{ powershell_module_2_maximum_version_request }}"
+    skip_publisher_check: yes
+    state: present
+  check_mode: yes
+  register: module_minimum_maximim_version_setup_1
+
+- name: "get result Powershell Gallery module setup - minimum_version and maximum_version - check mode: true"
+  win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_minimum_maximim_version_setup_1
+
+- name: "test Powershell Gallery module setup - minimum_version and maximum_version - check mode: true"
+  assert:
+    that:
+      - module_minimum_maximim_version_setup_1 is changed
+      - result_module_minimum_maximim_version_setup_1.stdout | trim | bool == false
+
+- name: "check Powershell Gallery module setup - minimum_version and maximum_version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module_2 }}"
+    minimum_version: "{{ powershell_module_2_minimum_version_request }}"
+    maximum_version: "{{ powershell_module_2_maximum_version_request }}"
+    skip_publisher_check: yes
+    state: present
+  register: module_minimum_maximim_version_setup_1
+
+- name: "get result Powershell Gallery module setup - minimum_version and maximum_version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_minimum_maximim_version_setup_1
+
+- name: "test Powershell Gallery module setup - minimum_version and maximum_version - check mode: false"
+  assert:
+    that:
+      - module_minimum_maximim_version_setup_1 is changed
+      - result_module_minimum_maximim_version_setup_1.stdout | trim | bool == true
+
+- name: check idempotency reinstalling module - minimum_version and maximum_version
+  win_psmodule:
+    name: "{{ powershell_module_2 }}"
+    minimum_version: "{{ powershell_module_2_minimum_version_request }}"
+    maximum_version: "{{ powershell_module_2_maximum_version_request }}"
+    state: present
+  register: module_minimum_maximim_version_setup_2
+
+- name: test idempotency reinstalling module - minimum_version and maximum_version
+  assert:
+    that:
+      - module_minimum_maximim_version_setup_2 is not changed
+
+- name: "check uninstall PowerShell module - minimum_version and maximum_version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module_2 }}"
+    minimum_version: "{{ powershell_module_2_minimum_version_request }}"
+    maximum_version: "{{ powershell_module_2_maximum_version_request }}"
+    state: absent
+  check_mode: yes
+  register: module_uninstall_minimum_maximum_version
+
+- name: "get result uninstall PowerShell module - minimum_version and maximum_version - check mode: true"
+  win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_uninstall_minimum_maximum_version
+
+- name: "test uninstall PowerShell module - minimum_version and maximum_version - check mode: true"
+  assert:
+    that:
+      - module_uninstall_minimum_maximum_version is changed
+      - result_module_uninstall_minimum_maximum_version.stdout | trim | bool == true
+
+- name: "check uninstall PowerShell module - minimum_version and maximum_version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module_2 }}"
+    minimum_version: "{{ powershell_module_2_minimum_version_request }}"
+    maximum_version: "{{ powershell_module_2_maximum_version_request }}"
+    state: absent
+  register: module_uninstall_minimum_maximum_version
+
+- name: "get result uninstall PowerShell module - minimum_version and maximum_version - check mode: false"
+  win_shell: "(Get-Module -Name {{ powershell_module_2 }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_2_minimum_maximum_version_result }}' } | Measure-Object).Count -eq 0"
+  changed_when: false
+  register: result_module_uninstall_minimum_maximum_version
+
+- name: "test uninstall PowerShell module - minimum_version and maximum_version - check mode: false"
+  assert:
+    that:
+      - module_uninstall_minimum_maximum_version is changed
+      - result_module_uninstall_minimum_maximum_version.stdout | trim | bool == true
+
+- name: check installing module with allow_clobber not active
+  win_psmodule:
+    name: "{{ allow_clobber_module }}"
+  register: fail_allow_clobber
+  ignore_errors: yes
+
+- name: test installing module with allow_clobber not active
+  assert:
+    that:
+      - fail_allow_clobber is failed
+      - "'The following commands are already available on this system' in fail_allow_clobber.msg"
+
+- name: "check installing module with allow_clobber active - check mode: true"
+  win_psmodule:
+    name: "{{ allow_clobber_module }}"
+    allow_clobber: yes
+  check_mode: yes
+  register: ok_allow_clobber
+
+- name: "get result installing module with allow_clobber active - check mode: true"
+  win_shell: "(Get-Module -Name {{ allow_clobber_module }}  -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_ok_allow_clobber
+
+- name: "test installing module with allow_clobber active - check mode: true"
+  assert:
+    that:
+      - ok_allow_clobber is changed
+      - result_ok_allow_clobber.stdout | trim | bool == false
+
+- name: "check installing module with allow_clobber active - check mode: false"
+  win_psmodule:
+    name: "{{ allow_clobber_module }}"
+    allow_clobber: yes
+  register: ok_allow_clobber
+
+- name: "get result installing module with allow_clobber active - check mode: false"
+  win_shell: "(Get-Module -Name {{ allow_clobber_module }}  -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_ok_allow_clobber
+
+- name: "test installing module with allow_clobber active - check mode: false"
+  assert:
+    that:
+      - ok_allow_clobber is changed
+      - result_ok_allow_clobber.stdout | trim | bool == true
+
+- name: "check uninstall PowerShell module allow_clobber - check mode: true"
+  win_psmodule:
+    name: "{{ allow_clobber_module }}"
+    state: absent
+  check_mode: yes
+  register: module_uninstall_4
+
+- name: "get uninstall PowerShell module allow_clobber - check mode: true"
+  win_shell: "(Get-Module -Name {{ allow_clobber_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 1"
+  register: result_module_uninstall_4
+
+- name: "test uninstall PowerShell module allow_clobber - check mode: true"
+  assert:
+    that:
+      - module_uninstall_4 is changed
+      - result_module_uninstall_4.stdout | trim | bool == true
+
+- name: "check uninstall PowerShell module allow_clobber - check mode: false"
+  win_psmodule:
+    name: "{{ allow_clobber_module }}"
+    state: absent
+  register: module_uninstall_4
+
+- name: "get uninstall PowerShell module allow_clobber - check mode: false"
+  win_shell: "(Get-Module -Name {{ allow_clobber_module }} -ListAvailable -ErrorAction Ignore | Measure-Object).Count -eq 0"
+  register: result_module_uninstall_4
+
+- name: "test uninstall PowerShell module allow_clobber - check mode: false"
+  assert:
+    that:
+      - module_uninstall_4 is changed
+      - result_module_uninstall_4.stdout | trim | bool == true
+
+- name: check installing module with allow_prerelease not active
+  win_psmodule:
+    name: "{{ allow_prerelease_module }}"
+    required_version: "{{ allow_prerelease_version }}"
+    allow_prerelease: no
+    skip_publisher_check: yes
+  register: fail_allow_prerelease
+  ignore_errors: yes
+
+- name: test installing module with allow_prerelease not active
+  assert:
+    that:
+      - fail_allow_prerelease is failed
+
+- name: "check installing prerelease module with allow_prerelease active - check mode: true"
+  win_psmodule:
+    name: "{{ allow_prerelease_module }}"
+    required_version: "{{ allow_prerelease_version }}"
+    allow_prerelease: yes
+    skip_publisher_check: yes
+  check_mode: yes
+  register: ok_allow_prerelease
+
+- name: "test installing prerelease module with allow_prerelease active - check mode: true"
+  assert:
+    that:
+      - ok_allow_prerelease is changed
+
+- name: "check installing prerelease module with allow_prerelease active - check mode: false"
+  win_psmodule:
+    name: "{{ allow_prerelease_module }}"
+    required_version: "{{ allow_prerelease_version }}"
+    allow_prerelease: yes
+    skip_publisher_check: yes
+  register: ok_allow_prerelease
+
+- name: "test installing prerelease module with allow_prerelease active - check mode: false"
+  assert:
+    that:
+      - ok_allow_prerelease is changed
+
+- name: check installing module with a wrong name
+  win_psmodule:
+    name: "{{ wrong_module }}"
+    state: present
+  ignore_errors: yes
+  register: module_fail
+
+- name: test installing module with a wrong name
+  assert:
+    that:
+      - module_fail is failed
+      - "'Problems installing {{ wrong_module }} module: No match was found for the specified search criteria' in module_fail.msg"
+
+- name: check installing module from Powershell Gallery - without version 3
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    state: present
+  register: module_without_version_setup_3
+
+- name: get result installing module from Powershell Gallery - without version 3
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ module_latest_version.stdout | trim }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_without_version_setup_3
+
+- name: test Powershell Gallery module setup - without version 3
+  assert:
+    that:
+      - module_without_version_setup_3 is changed
+      - result_module_without_version_setup_3.stdout | trim | bool == true
+
+- name: check installing module from Powershell Gallery - required_version 4
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    required_version: "{{ powershell_module_required_version }}"
+    state: present
+  register: module_required_version_setup_4
+
+- name: get result installing module from Powershell Gallery - required_version 4
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_required_version_setup_4
+
+- name: test installing module from Powershell Gallery - required_version 4
+  assert:
+    that:
+      - module_required_version_setup_4 is changed
+      - result_module_required_version_setup_4.stdout | trim | bool == true
+
+- name: "check uninstall PowerShell module - required_version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    required_version: "{{ powershell_module_required_version }}"
+    state: absent
+  check_mode: yes
+  register: module_uninstall_required_version
+
+- name: "get result uninstall PowerShell module - required_version - check mode: true"
+  win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ powershell_module_required_version }}' } | Measure-Object).Count -eq 1"
+  changed_when: false
+  register: result_module_uninstall_required_version
+
+- name: "test PowerShell module uninstall - required_version - check mode: true"
+  assert:
+    that:
+      - module_uninstall_required_version is changed
+      - result_module_uninstall_required_version.stdout | trim | bool == true
+
+- name: "check uninstall PowerShell module - minimum_version - ultra high version - check mode: true"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    minimum_version: "{{ powershell_module_ultra_high_version }}"
+    state: absent
+  check_mode: yes
+  register: module_uninstall_minimum_version
+
+- name: "test Powershell Gallery module setup - minimum_version - ultra high version - check mode: true"
+  assert:
+    that:
+      - module_uninstall_minimum_version is not changed
+
+- name: "check uninstall PowerShell module - minimum_version - ultra high version - check mode: false"
+  win_psmodule:
+    name: "{{ powershell_module }}"
+    minimum_version: "{{ powershell_module_ultra_high_version }}"
+    state: absent
+  register: module_uninstall_minimum_version
+
+- name: "test Powershell Gallery module setup - minimum_version - ultra high version - check mode: false"
+  assert:
+    that:
+      - module_uninstall_minimum_version is not changed
+
+- name: check fake custom ps repository registration attempt
+  win_psmodule:
+    name: "{{ wrong_module }}"
+    repository: "{{ fake_repo_name }}"
+  ignore_errors: yes
+  register: fake_repo_fail
+
+- name: test fake custom ps repository registration attempt
+  assert:
+    that:
+      - fake_repo_fail is failed
+
+- name: check installing module from the My Get repository and registering that repository at the same time
+  win_psmodule:
+    name: "{{ myget_powershell_module }}"
+    repository: "{{ myget_repository_name }}"
+    url: "{{ myget_repository_url }}"
+    state: present
+  register: adding_repository
+
+- name: get installing module from the My Get repository and registering that repository at the same time
+  win_shell: |
+    $repo = Get-PSRepository -Name {{ myget_repository_name | quote }} -ErrorAction Ignore
+    $module = Get-Module -Name {{ myget_powershell_module }} -ListAvailable
+    ($repo | Measure-Object).Count
+    $repo.SourceLocation
+    $repo.InstallationPolicy
+    ($module | Measure-Object).Count
+  register: result_adding_repository
+
+- name: test installing module from the My Get repository and registering that repository at the same time
+  assert:
+    that:
+    - adding_repository is changed
+    - result_adding_repository.stdout_lines[0] == '1'
+    - result_adding_repository.stdout_lines[1] == myget_repository_url
+    - result_adding_repository.stdout_lines[2] == 'Trusted'
+    - result_adding_repository.stdout_lines[3] == '1'
+
+- name: check uninstalling module from the My Get repository and unregistering that repository at the same time
+  win_psmodule:
+    name: "{{ myget_powershell_module }}"
+    repository: "{{ myget_repository_name }}"
+    state: absent
+  register: removing_repository
+
+- name: get uninstalling module from the My Get repository and registering that repository at the same time
+  win_shell: |
+    $repo = Get-PSRepository -Name {{ myget_repository_name | quote }} -ErrorAction Ignore
+    $module = Get-Module -Name {{ myget_powershell_module }} -ListAvailable
+    ($repo | Measure-Object).Count
+    ($module | Measure-Object).Count
+  register: result_removing_repository
+
+- name: test uninstalling module from the My Get repository and registering that repository at the same time
+  assert:
+    that:
+    - removing_repository is changed
+    - result_removing_repository.stdout_lines[0] == '0'
+    - result_removing_repository.stdout_lines[1] == '0'
+
+# I don't know why Publish-Module doesn't work correctly under Ansible and PowerShell 3.0
+- name: check operations related to the custom repository
+  when: powershell_major_version.stdout | int >= 4
+  block:
+    - name: "check sample module is uninstalled - check mode: false"
+      win_psmodule:
+        name: "{{ powershell_module }}"
+        state: absent
+      register: module_uninstall_4
+
+    - name: "create repository path - check mode: false"
+      win_file:
+        path: "{{custom_repo_path}}"
+        state: directory
+
+    - name: "copy some module to custom repo - check mode: false"
+      win_shell: |
+        $ErrorActionPreference = "Stop"
+
+        Save-Module -Name "{{powershell_module}}" -Repository PSGallery -Path $env:Temp | Out-Null
+
+        $repoName = "{{custom_repo_name}}"
+        $repoPath = "{{custom_repo_path}}"
+
+        Register-PSRepository -Name $repoName -SourceLocation $repoPath -InstallationPolicy Trusted | Out-Null
+
+        Publish-Module -Repository PSRegisterRepo -Path "$env:temp\Powershell-yaml" -Force -Confirm:$false -Verbose | Out-Null
+
+        Start-Sleep -Seconds 15
+
+        Get-ChildItem -Path $repoPath\* -include *.nupkg | Where-Object { $_.Name -match "{{powershell_module}}" } | ForEach-Object { $_.Name }
+
+      register: saved_package
+
+    - name: "check installing module from custom Powershell repository - check mode: true"
+      win_psmodule:
+        name: "{{ powershell_module }}"
+        state: present
+        repository: "{{custom_repo_name}}"
+      check_mode: yes
+      register: module_from_custom_repo
+
+    - name: "test sample module in custom repo - check mode: false"
+      assert:
+        that:
+          - powershell_module | lower in ((saved_package.stdout_lines | last) | lower)
+
+    - name: "get the latest version of module in custom repo"
+      win_shell: "((Find-Module -Name {{ powershell_module }} -Repository {{custom_repo_name}}).Version).ToString()"
+      changed_when: false
+      register: saved_module_latest_version
+
+    - name: "get result installing module from custom Powershell repository - check mode: true"
+      win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ saved_module_latest_version.stdout }}' } | Measure-Object).Count -eq 1"
+      changed_when: false
+      register: result_module_from_custom_repo
+
+    - name: "test installing module from custom Powershell repository - check mode: true"
+      assert:
+        that:
+          - module_from_custom_repo is changed
+          - result_module_from_custom_repo.stdout | trim | bool == false
+
+    - name: "check installing module from custom Powershell repository - check mode: false"
+      win_psmodule:
+        name: "{{ powershell_module }}"
+        state: present
+        repository: "{{custom_repo_name}}"
+      register: module_from_custom_repo
+
+    - name: "get result installing module from custom Powershell repository - check mode: false"
+      win_shell: "(Get-Module -Name {{ powershell_module }} -ListAvailable -ErrorAction Ignore | Where-Object { $_.Version -eq '{{ saved_module_latest_version.stdout }}' } | Measure-Object).Count -eq 1"
+      changed_when: false
+      register: result_module_from_custom_repo
+
+    - name: "test installing module from custom Powershell repository - check mode: false"
+      assert:
+        that:
+          - module_from_custom_repo is changed
+          - result_module_from_custom_repo.stdout | trim | bool == true
+
+    - name: test module was installed from custom repo
+      win_shell: "(Get-InstalledModule -Name {{ powershell_module }}).Repository"
+      register: is_package_customrepo
+
+    - name: test sample module is installed from custom repo
+      assert:
+        that:
+          - is_package_customrepo.stdout_lines[0] == custom_repo_name
diff --git a/test/integration/targets/win_psmodule/tasks/test.yml b/test/integration/targets/win_psmodule/tasks/tests_legacy.yml
similarity index 81%
rename from test/integration/targets/win_psmodule/tasks/test.yml
rename to test/integration/targets/win_psmodule/tasks/tests_legacy.yml
index c6b2994324b..32a70bfd51d 100644
--- a/test/integration/targets/win_psmodule/tasks/test.yml
+++ b/test/integration/targets/win_psmodule/tasks/tests_legacy.yml
@@ -1,5 +1,15 @@
+# This file is part of Ansible
+
+# test code for the win_psmodule module when using winrm connection
+# Copyright: (c) 2017, Daniele Lazzari <lazzari@mailup.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
 ---
 
+# The file contains tests for backward compatibility only - for Ansible < 2.8.
+# They should be removed under a deprecation of the functionalities for adding/removing
+# repositories.
+
 - name: install module from Powershell Gallery
   win_psmodule:
     name: "{{ powershell_module }}"
@@ -46,7 +56,7 @@
       - "ok_allow_clobber is changed"
 
 - name: check wrong module install attempt
-  win_psmodule: 
+  win_psmodule:
     name: "{{ wrong_module }}"
     state: present
   ignore_errors: yes
@@ -146,35 +156,35 @@
 - name: Copy some module to custom repo
   win_shell: |
     # Need PSGet 1.6.0 for publishing and named repo usage
-    $psg = [PSCustomObject]@{ n="PowerShellGet"; v="1.6.0"};
-    Remove-Module -Name $psg.n -Force -EA SilentlyContinue;
-    Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -EV missingProvider -Force | Out-Null;
+    $psg = [PSCustomObject]@{ n="PowerShellGet"; v="1.6.0"}
+    Remove-Module -Name $psg.n -Force -ErrorAction SilentlyContinue
+    Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -ErrorVariable missingProvider -Force | Out-Null
 
     if($missingProvider){
-      Install-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Confirm:$false -Force | Out-Null;
-      
+      Install-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Confirm:$false -Force | Out-Null
+
       # Unload previous version
-      Remove-Module -Name $psg.n -Force -EA SilentlyContinue;
-      Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Force | Out-Null;
+      Remove-Module -Name $psg.n -Force -ErrorAction SilentlyContinue;
+      Import-PackageProvider -Name $psg.n -RequiredVersion $psg.v -Force | Out-Null
     }
 
-    $modName = "{{powershell_module}}";
-    $temp = $env:Temp;
+    $modName = "{{powershell_module}}"
+    $temp = $env:Temp
 
-    Save-Module -Name $modName -Repository PSGallery -Path $temp | Out-Null;
+    Save-Module -Name $modName -Repository PSGallery -Path $temp | Out-Null
 
-    $repoName = "{{custom_repo_name}}";
-    $repoPath = "{{custom_repo_path}}";
+    $repoName = "{{custom_repo_name}}"
+    $repoPath = "{{custom_repo_path}}"
 
     if(!(Test-Path $repoPath)){
-      New-Item -Type Directory $repoPath -Force | Out-Null;
+      New-Item -Type Directory $repoPath -Force | Out-Null
     }
 
-    Register-PSRepository -Name $repoName -SourceLocation $repoPath -InstallationPolicy Trusted | Out-Null;
-    
-    Publish-Module -Path "$temp\\$modName" -Repository $repoName -Force -Confirm:$false | Out-Null;
-    Get-ChildItem "$repoPath\\*" | ? Name -match "$modName.*.nupkg" | % Name;
-    
+    Register-PSRepository -Name $repoName -SourceLocation $repoPath -InstallationPolicy Trusted | Out-Null
+
+    Publish-Module -Path "$temp\\$modName" -Repository $repoName -Force -Confirm:$false | Out-Null
+    Get-ChildItem -Path "$repoPath\\*" | Where-Object { $_.Name -match "$modName.*.nupkg" } | ForEach-Object { $_.Name }
+
   register: saved_package
 
 - name: Validate sample module in custom repo
diff --git a/test/sanity/pslint/ignore.txt b/test/sanity/pslint/ignore.txt
index dc8a96d75c2..3b5340e733a 100644
--- a/test/sanity/pslint/ignore.txt
+++ b/test/sanity/pslint/ignore.txt
@@ -52,7 +52,6 @@ lib/ansible/modules/windows/win_pagefile.ps1 PSAvoidUsingPositionalParameters
 lib/ansible/modules/windows/win_pagefile.ps1 PSAvoidUsingWMICmdlet
 lib/ansible/modules/windows/win_pagefile.ps1 PSUseDeclaredVarsMoreThanAssignments
 lib/ansible/modules/windows/win_pagefile.ps1 PSUseSupportsShouldProcess
-lib/ansible/modules/windows/win_psmodule.ps1 PSAvoidUsingCmdletAliases
 lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 PSAvoidUsingCmdletAliases
 lib/ansible/modules/windows/win_rabbitmq_plugin.ps1 PSAvoidUsingInvokeExpression
 lib/ansible/modules/windows/win_region.ps1 PSAvoidUsingEmptyCatchBlock