Thursday, October 16, 2025

AutoPackager V3: Winget to Intune Automation

AutoPackager v3: Winget to Intune Automation

Purpose:

To assist others in reducing toil in packaging and deploying applications in Intune that are available within Winget. To allow them to take advantage of the code provided and inspire new functionality and features. This is made available without warranty or support. Use at own risk.

Problem:

Packaging applications within Intune and keeping them regularly updated can take a significant amount of time, especially if you host a large software catalog. I wanted to create a workflow that would assist, standardize, and automate this process as much as possible while keeping to native Intune application deployment mechanisms.  There are others that have tried to do Winget integrations, but I feel this one allows for the greatest customization and work within the Intune deployment processes best.

Solution:

I created several PowerShell scripts that when ran together simplify and automate many of the tasks needed to keep an application catalog up to date with minimal effort. Currently these scripts can only help automate what is in the Winget repository database. It works by creating recipe files for each of the applications you wish to import into your application catalog.

Prerequisites:

1.      Create a Microsoft Entra App Registration

a.      Give the API permissions DeviceManagementApps.ReadWrite.All and DeviceManagementConfiguration.ReadWrite.All for Application type.

                                                              i.      Grant Admin Consent for these new permissions.

b.      Create a new Client secret

                                                              i.      Ensure you keep track of the Secret ID and the Value as these will be needed later.

2.      Create a GitHub PAT Token (will be needed or you will hit api limits with GitHub when running AutoPackager)

3.      Download all AutoPackager V3 files from my GitHub

a.      Read the Readme and SystemConfigReadMe.txt

b.      Update AutoPackager.config.json

                                                              i.      Required areas to update are the AzureAuth section and GitHubToken

1.      AzureAuth should work with CertificateThumbprint but I have only used and tested Client Secret.

                                                            ii.      Remember: This is a json file. If you are adding network paths, you have to double the \ in your path.  Example: \\\\server.server.com\\share name\\folder name

c.      Launch AutoPackager.GUI.ps1 and run the Prerequisite checker (Install any modules or fix any issues it finds)

4.      Setup Automation

a.      Scheduled task on a workstation or server that will run Autopackager and read the recipes nightly.

5.      Automation Account

a.      Create a local windows account or domain service account that can be used as the account for the scheduled task.  System may work too, but if you do not choose a domain account you will not be able to archive to a network folder (setup in the autopackager.config.json file.

How it works:

Searching Winget and testing installer

After completing all prerequisites, it is best to start with AutoPackager.GUI.ps1. On the Winget tab the GUI allows you to search the Winget repository for the application you want to automate. Once found, you can show the Winget application YAML file for the latest installer URLs and the types of installers available (x64, x86, arm, exe, msi, etc.). Once you determine what installer you want to use update the Winget tab further with the installer type wanted and click download installer.  This will allow you to test the installer manually and figure out what switches and options are needed to make it a silent install.  Be sure to keep track of these switches as they will be needed later in the recipe section. For silent uninstall, it is recommended to look in the registry for the Uninstall string of the newly installed application under the following locations;

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\.

Once the uninstall string is found test different switches to determine how to make it uninstall silently and record for the recipe step later. Remember only the switches will be needed for the Recipe section later.

Create stub Intune applications

On the Intune App(s) tab you will need to create two Intune applications. Ensure you pick your icon prior to creating the applications. The icon is what will be used in Company Portal. The Primary application will be for what is made available or as a required application to your user population. The other Required Update application will have a suffix of – Required Update and will be used in the future to keep any devices with a previous version updated. These two buttons will only create a stub record and will not deploy to anything.

Create your Recipe

On the Recipe tab, fill in all the information you can from your testing and the application stubs. There is a lot of options on this page, please refer to the help tab if you have questions on them. If you followed the process up to this point you should have the Winget ID, PrimaryAppId, Required Update AppId, Architecture, Installer Type, Installer Scope (Should always be machine), InstallArgs, and UninstallArgs filled in at this point. InstallArgs and UninstallArgs are just the switches you found earlier in your testing. DO NOT give full paths to the exe/msi or the full uninstall string found in the registry. ONLY the switches. If you know other areas, you can update them as well. Once complete click Create New Recipe, and it will create it in the Recipe location stored in the autopackager.config.json file. You will update the recipe further as the process continues.

Run AutoPackager in Package Only and Full Run modes

On the Run tab you should see two modes. Ensure Package Only mode is selected and ensure your recipe file is in the target box then click Run AutoPackager. This will do all the automated functions to package up and do all the steps except for uploading to Intune. Once Package Only mode is ran, you will find all of the output files and scripts in the Working folder. From there you will be able to test the install.ps1 and uninstall.ps1 scripts.  You will also need to test and ensure that the Requirement and Detection scripts respond with TRUE when the application is installed. The scripts also log to C:\ProgramData\Microsoft\IntuneManagementExtension\Logs so you can validate. If all scripts work and report back properly it is time to Run in Full Run mode.  This will upload all the files and scripts to the application stubs created earlier.

Test deployment with Intune

Find your new application in Intune and assign some test groups.  Validate the install and uninstall work properly. If something doesn’t work and the recipe needs to be updated and tested again you will need reset the stub applications before updating the recipe and testing again.  To Reset the applications back to original stub states then go the to Reset tab and ensure the correct Primary AppId and Required Update AppId are populated and then click the Reset buttons.

Finalize Recipe

Once you have your recipe file set the way you want, and your deployment ring groups set for the required updates then it is time to move the recipe to your automation server.

Automation

Once AutoPackager is configured on your local machine and verified that things are working with a single recipe, it is best to copy your local directory to an automation machine (Windows Server or another Windows workstation). You will want to create a scheduled task to run everything. 

Task Scheduler Setup

1.      General tab

a.      Select your account

b.      Run whether user is logged on or not

c.      Run with highest privileges

2.      Triggers tab

a.      Begin on a schedule

b.      Daily (Pick your time)

c.      Enabled (checked)

3.      Actions tab

a.      Start a program

b.      Program/Script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

c.      Add arguments: -NoProfile -executionpolicy bypass -file ".\autopackagerv2.ps1" -fullrun -allrecipes

d.      Start in: (Directory you copied the AutoPackager files)

Closing:

I hope this helps others. I will most likely keep developing this to be more feature rich and will update my GitHub page as new updates are made.  I will not be active in my responses but feel free to leave comments if you wish.  I do check them occasionally and will respond as time allows. If you take this code and develop it further, please leave a comment on where you make it available and what updates you made.  I would be interested to see where this can go.

Tuesday, March 30, 2021

SCCM/MEM ContentLibraryCleanUp.exe Automation

Purpose:

To help others take what I have done and use for their own environment with modifications or to improve upon what I have done for others to use in the future.  Use at own risk.

Problem:

The SCCMContentLib was growing beyond what it should.  Orphaned package data was being left behind.  This was happening on many of our Distribution Points and began throwing errors for low disk space.  Found the Microsoft provided ContentLibraryCleanup.exe but it was a very manual process to run across our enterprise.

Solution:

I created a couple scripts that could either be ran locally on the DP or remotely from a machine that had the SCCM/MEM Admin Console installed.  These scripts were written with a hierarchy of a single primary site server.  This will not run on a Primary Site Server with DP role.

Prerequisites: (Only 1 script is needed)

ContentLibraryCleanup-Local.ps1 – Run manually on DP or create a package and call within a Task Sequence to automate. (FAST)

ContentLibraryCleanup-Remote.ps1– Run manually from a remote machine or setup as a scheduled task to automate. (SLOW)

ContentLibraryCleanup.exe – Find in CD.Latest\SMSSETUP\TOOLS\ContentLibraryCleanup on the site server

How it works:

ContentLibraryCleanup-Local.ps1: Place script and contentlibrarycleanup.exe in the same folder.  Run the script from powershell.  The script will gather the FQDN of the machine and start logging.  It will start running in WhatIF mode and if successful it will run in Delete mode.  The logs from the script can be found at c:\windows\logs\contentlibrarycleanup\ and the logs from ContentLibraryCleanup.exe can be found in the folder where the script and exe reside.

To automate it further I created a Package in SCCM with the script and contentlibrarycleanup.exe in the same folder.  No Program was required.  Then I created a Task Sequence with a single task of Run PowerShell Script.  I pointed this task at the package, script name: ContentLibraryCleanup-local.ps1, Execution Policy: Bypass, and selected run this step as the following account and provided credentials that had Admin rights locally as well as to the SCCM environment. Once the TS was created I deployed it to a collection that only had Distribution Points in it.

 

ContentLibraryCleanup-Remote.ps1: Place script and contentlibrarycleanup.exe in the same folder.  The SCCM console must reside on the same machine.  Run the script from powershell.  The script will ask you for your site code and the primary site server.  It will then gather all the Distribution Points in the environment and start logging.  It will start running in WhatIF mode and if successful it will run in Delete mode for each DP it finds.  The logs from the script can be found at c:\windows\logs\contentlibrarycleanup\ and the logs from ContentLibraryCleanup.exe can be found in the folder where the script and exe reside.

To automate it further you could change the prompts for site code and primary site server to parameters and then feed the script the parameters and set it as a scheduled task that will run with admin rights to the remote DPs as well as SCCM.

Additional Info:

Content library cleanup tool - Configuration Manager | Microsoft Docs

Tuesday, June 30, 2020

Change/Update SCCM-MEM Certificates

Change/Update SCCM-MEM Certificates

Purpose:

To help others take what I have done and use for their own environment with modifications or to improve upon what I have done for others to use in the future.  Use at own risk.

Problem:

We were moving to a new PKI environment with new CA and SubCAs.  We needed to update our certificates on our SCCM/MEM infrastructure servers.  This included client authentication, distribution point, management point, and software update point certificates.  Our environment had 80+ DPs, 2 MPs, and 1 Primary Site Server.

Solution:

WinRM was already enabled.  We pushed the new Root CA and SubCA to the infrastructure servers using GPO then created a few scripts to automate the needed tasks to update the certificates.  This included the certificate request, export, IIS binding, and importing the certificate into the console for DPs.  This took our change/update tasks from multiple hours to change over to ~45 min and almost all of which was just script runtime and just monitoring the console output.

Scripts:

Script 1 – Enable CredSSP on infrastructure servers

Script 2 – Certificate request, export, and bind IIS certificate

Script 3 – Import DP certificate into the console.

Modifications:

All areas that need to be modified are in “< >” symbols

Script 2

1.      Production - Line 6, 9, 15, 21, 33

2.      Testing - Line 97-103

3.      Error/Resume - Line 116

Script 3

1.      Production - Line 45, 50

Wednesday, February 5, 2020

Modern Driver Management - Task Sequence

Modern Driver Management – Task Sequence

Problem

I wanted to update my drivers only once and have it update all my task sequences that use drivers.  Usually each of my task sequences for operating system deployments or operating system upgrades had their own driver sets in the sequences.

Solution

I created was a new task sequence that would hold all the drivers for all our known hardware models.  This TS would be called from our deployment or upgrade task sequences.  This sequence will utilize a TS variable to identify if the hardware model is known or not and Download Package Content tasks. You will need a separate Driver Package or Package with the driver files for each hardware model.  You will also need an “empty” Driver Package or Package so the OS Deployment and OS Upgrade sequences can work correctly.  In your empty package you will need to place something in it as it will not want to replicate unless it has something in it.  Either a small text file if you made a package or a small driver if it is a Driver Package.  Keep reading to see how this works. 

Inspiration

The below link seemed like it made this a lot harder to implement.  I did not try it so I cannot speak to the difficulty, but it was a lot of info. https://deploymentresearch.com/configmgr-driver-management-in-just-four-steps-by-matthew-teegarden/

Process

Create the new driver task sequence

1.      Create two task sequence variable tasks called OSDKnownModels

a.      The first TS variable should have a value of NO

b.      The second TS variable should have a value of YES and Options tab should have WMI queries

2.      The Known PC Model Upgrades group should have a condition of TS Variable OSDKnownModels = YES

3.      Each Driver model needs to be setup as a Download Package Content task along with a wmi condition for the driver model under the Known PC Model Group.  It also needs to have the following options selected

a.      Place into the following location: Task sequence working directory

b.      Check – Save path as a variable: Driver Pack

4.      Unknown PC Models group needs to have a TS Variable condition of OSDKnownModels = NO

5.      Place your Unknown Model driver package or package in the Unknown PC Models group.  This package does not need to have any conditions.  It also needs to have the following options selected

a.      Place into the following location: Task sequence working directory

b.      Check – Save path as a variable: Driver Pack

Operating System Upgrade Task Sequence

1.      Your OS Upgrade Task needs to have two tasks to work successfully.

2.      Create a new Run Task Sequence task and browse to your Model Drivers Task Sequence

3.      Create a new Upgrade Operating System task

a.      Select your Upgrade Package and Edition

b.      Check – Provide the following driver content to Windows Setup during upgrade

                                                    i.     Select Staged content: type %DriverPack01%

1.      DriverPack is the variable from the driver TS but 01 is because the driver was the 1st package in the Download Package Content task.

Operating System Deployment Task Sequence

1.      After the Apply Operating System Task and while still in Windows PE add a new task

2.      Create a Run Task Sequence task and browse to the Drivers Task Sequence you created above

3.      Create a Run Command Line task to inject the drivers into the Windows Install

a.      Command line should be: DISM.exe /Image:%OSDISK%\ /Add-Driver /Driver:%DriverPack01%\ /Recurse

b.      %OSDISK% is the variable we use in our Format tasks as well as Apply Operating System tasks

c.      %DriverPack01% is the variable that is created from the Driver Task Sequence

Conclusion

Please ask if there are any questions.  I will try to answer as time permits.

Wednesday, June 14, 2017

ConfigMgr Current Branch Custom Task Sequence Variable for Computer Role

ConfigMgr Current Branch Custom Task Sequence Variable for Computer Role

Problem

I needed a way to identify the type or role a machine was going to be within the PE portion of an OSD sequence.  The initial thought was to read the computer name with wmi and use the like variable to control different actions within the task sequence.  This would have worked but I needed to get this information within Windows PE and the computer name would typically be MININT-xxxxxx.  You could call the task sequence variable _SMSTSMachineName or OSDComputerName but a task sequence variable can only be equal or not equal.  The like variable is not allowed on any task sequence variable.

Resolution

I created a PowerShell script that will create a custom OSD Task Sequence Variable called OSDComputerRole.  This script is set to run after the computer naming script that I created in a previous post found here.  You can download the previous posts scripts and files from here.  This new script is set to run after the OSDComputerName variable is set.  The new script also uses the same csv file that the naming script utilized which is explained in the previous post.  The OSDComputerRole allows for the computer role to be read from the csv file and then you can call the task sequence variable as a condition to the task sequence step.  I hope this helps someone else in their search to do something similar.  The code to the PowerShell script is below and can be downloaded from here.

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment

 

$ComputerName = $tsenv.Value('OSDComputerName')

$csv = Import-Csv .\Win10OUMap.csv -delimiter ';'

    foreach ($line in $csv) { 

        IF ($computername -Match $line.NAME){

            $tsenv.Value('OSDComputerRole') = $line.Role

                                           Exit

            }

        Else {

            $tsenv.Value('OSDComputerRole') = 'Unknown'

            }

    }

 

 

Tuesday, July 19, 2016

ConfigMgr 2012 Name Computer During OSD Task Sequence

ConfigMgr 2012 Name Computer During OSD Task Sequence

Problem

I needed a way to prompt for computer name during the OSD sequence.  I found an old post by texasmcse found here that got me started.  The second part that was needed was to get some validation around the name that is input so it would follow our naming standards.

Resolution

 

I created a new script with parts of code from the post above to prompt for a site code, then prompt for computer role, and finally it takes the last 7 characters of the serial to form the computer name.  It uses a csv file to validate the site code and role are correct before moving on.  If there is an incorrect configuration it will respond and start over.  It will check the computer name that is stored in the task sequence variable _SMSTSMachineName.  If the variable is set to MININT it will prompt for computer naming.  If it is set to something else, it will utilize what ConfigMgr is passing it.  I hope this is useful to others.  I am sure the code could be cleaner but it works well. In the code the CSV file is named Win10OUMap.csv.  The Win10OUMap.csv file has 5 columns in the following order; Name,OU,BusinessUnit,SiteCode,Role.  This is a ; delimited file.  The Name column is what is used to validate the name of the computer as it will contain the site and role format to ensure it is valid.  When you modify the script file remember that when you import a CSV file in VB the first column is 0 not 1.  Again hope this helps.

Code:

'On Error Resume Next

Set WshShell = WScript.CreateObject("WScript.Shell")

Set NetworkObject = CreateObject("WScript.Network")

Set objFSO = CreateObject("Scripting.FileSystemObject")

set SCCMenv = CreateObject("Microsoft.SMS.TSEnvironment")

 

'Find if known in SCCM

NameLookup = SCCMenv("_SMSTSMachineName")

'NameLookup = "MININT-234343"

SearchChar = "MININT"

'msgbox NameLookup

StrComputer = "."

IF inStr(NameLookup , SearchChar) Then

              SiteCodeMatch = 10

              SiteRoleMatch = 10

              PCNameMatch = 10

              Validated = False

                             'Get Computer Serial Number

              Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

              Set colSMBIOS = objWMIService.ExecQuery ("Select * from Win32_SystemEnclosure")

              For Each objSMBIOS in colSMBIOS

              SNStr = objSMBIOS.SerialNumber

              SNShort = RIGHT(SNStr,7)

                             'msgbox snshort

 

              Do While answer <> vbYes

                             Do While Validated = False

                                           Do while SiteCodeMatch < 20

                                                          set SiteCodeFile = objFSO.OpenTextFile("Win10OUMap.csv")

 

                                                          SiteCode = InputBox ("Enter the 4 Character Site Code" & vbCrLf & "I.e. CORP=Corporate, OLME=Mesa, INDY=Indianapolis etc..", "Prompt for Site Code:",,0,0)

                                                          SiteCode = UCase(SiteCode)

                                                          'msgbox SiteCode

                                                                        Do while NOT SiteCodeFile.AtEndOfStream

                                                                                      arrStrSiteCode = split(sitecodefile.ReadLine,";")

                                                                                       strSiteCode = arrStrSiteCode(3)

                                                                                      IF SiteCode = strSiteCode Then

                                                                                      'msgbox "EQUALS " & strSiteCode & " " & SiteCode

                                                                                      'msgbox "I Match"

                                                                                      SiteCodeMatch = 20

                                                                                      Exit Do

                                                                                      Else

                                                                                      'msgbox "Not Equal " & strSiteCode & " " & SiteCode

                                                                                      'msgbox "I dont match"

                                                                                      End IF

                                                                        loop

                                                                        SiteCodeFile.Close

                                                                        IF SiteCodeMatch < 20 Then

                                                                        MsgBox  "Invalid Site Code!  Site Codes are defined as a 4 Character Location, I.e. CORP=Corporate, OLME=Mesa OpenLane, INDY=Indianapolis, BOST=Boston, OLTO=Toronto Openlane etc.. If you do not know your site code please contact the ServiceDesk.", 69680

                                                                        Else

                                                                        End IF

                                           Loop

 

                                           'wscript.echo SiteCode

                                           'wscript.echo SiteCodeMatch

 

                                           Do while RoleCodeMatch < 20

                                                          set RoleCodeFile = objFSO.OpenTextFile("Win10OUMap.csv")

 

                                                          RoleCode = InputBox ("Enter the Single Character function role of the Computer," & vbCrLf & "i.e. W=Workstation L=Laptop K=Kiosk, B=Block, D=Digital Arb etc...", "Enter the Computer Role for " & sitecode & ":",,0,0)

                                                          RoleCode = UCase(RoleCode)

                                                          'msgbox RoleCode

                                                                        Do while NOT RoleCodeFile.AtEndOfStream

                                                                                      arrStrRoleCode = split(RoleCodefile.ReadLine,";")

                                                                                      strRoleCode = arrStrRoleCode(4)

                                                                                      IF RoleCode = strRoleCode Then

                                                                                      'msgbox "EQUALS " & strRoleCode & " " & RoleCode

                                                                                      'msgbox "I Match"

                                                                                      RoleCodeMatch = 20

                                                                                      Exit Do

                                                                                      Else

                                                                                      'msgbox "Not Equal " & strRoleCode & " " & RoleCode

                                                                                      'msgbox "I dont match"

                                                                                      End IF

                                                                        loop

                                                                        RoleCodeFile.Close

                                                                        IF RoleCodeMatch < 20 Then

                                                                        MsgBox  "Invalid Role Code!  Roles are Defined as a single character for the function of the Computer i.e. W=Workstation L=Laptop, K=Kiosk, B=Block, D=Digital Arb etc.. If you do not know the Function codes for site " & SiteCode & " please contact the ServiceDesk.", 69680

                                                                        Else

                                                                        End IF

                                           Loop

 

                                           'wscript.echo RoleCode

                                           'wscript.echo RoleCodeMatch

                                           PCName = SiteCode & "-" & RoleCode & "-" & SNShort

                                           set PCNameFile = objFSO.OpenTextFile("Win10OUMap.csv")

                                           Do while NOT PCNameFile.AtEndOfStream

                                                          arrStrPCName = split(PCNamefile.ReadLine,";")

                                                          strPCName = arrStrPCName(0)

                                                          IF inStr(PCName , strPCName) Then

                                                          'msgbox "EQUALS " & strPCName & " " & PCName

                                                          'msgbox "I Match"

                                                          PCNameMatch = 20

                             '                            Exit Do

                                                          Else

                                                          'msgbox "Not Equal " & strPCName & " " & PCName

                                                          'msgbox "I dont match"

                                                          End IF

                                           loop

                                           PCNameFile.Close

                                           IF PCNameMatch < 20 Then

                                           MsgBox  "PC Name is Invalid!  PC Name does not meet the standards in the PC Name to OU Map file.  If you do not know the naming standards for the site " & SiteCode & " please contact the ServiceDesk.", 69680

                                           Validated = False

                                           SiteCodeMatch = 10

                                           RoleCodeMatch = 10

                                           Else

                                           'MsgBox "PCNameValid"

                                           Validated = True

                                           End IF

                            

                             Loop

                                           If PCNameMatch = 20 Then

                                                          answer = MsgBox("Are you sure this correct?" & vbCrLf & PCName, 69668, "Verify Name")

                                                          IF answer = vbNo then

                                                                        SiteCodeMatch = 10

                                                                        RoleCodeMatch = 10

                                                                        Validated = False

                                                          Else

                                                         

                                                          PCNameFinal = PCName

                                                          'msgbox PCNameFinal

                                                          SCCMenv("OSDComputerName") = PCNameFinal

                                                          End If

                                           Else

                                           answer = vbNo

                                           End IF

              loop

              Next

Else

'msgbox "Did not match"

End IF

Friday, July 8, 2016

PowerShell failing in a ConfigMgr 2012 OSD Task Sequence

PowerShell failing in a ConfigMgr 2012 OSD Task Sequence

Problem

We had a PowerShell script trying to be executed from a Command Line task within our OSD Task Sequence.  This was failing with either running the command manually or calling it from within the package within the OSD Task Sequence.  What was odd and troublesome is if I ran the same commands within its own Custom Task Sequence outside of the OSD Task Sequence it would work.  The error that was seen in the smsts.log file was The term XXX is not recognized as the name of a cmdlets, function, script file, or operable program.  Check the spelling of the name, or if a path was included, verify the path is correct and try again.”  This error was found for almost every PowerShell action that the script was performing.

Resolution

I came across a post by Mike Griswold found here that explained part of the issue.  The issue is that when PowerShell is called within an OSD Task Sequence and within the OS (NOT PE) it does not have any modules loaded like default.  What I had to do was from the OS open PowerShell and run my script.  After the script completed I ran Get-Module from within the same PowerShell window.  This step was important as when running Get-Module by default from a fresh PowerShell window it will not give you all the modules the script referenced. After running Get-Module from within the same PowerShell window after the script ran it gave me the Modules that the script required.  I then modified my PowerShell script that I was using within my SCCM package to include the needed modules.  The specific lines I added to my .PS1 file are listed below.  I added the -verbose so I could see within the SMSTS.log file that the modules were in fact importing correctly.  After this modification everything started working as expected and my sanity returned.

import-module -Name C:\windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Management -verbose

import-module -Name C:\windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Security -verbose

import-module -Name C:\windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Utility -verbose