PowerShell: Automatically load scripts or functions when starting PowerShell

Scenario: You want to kick off certain scripts or functions when opening PowerShell

Solution:
1. Navigate to: C:\Users\<you>\Documents\WindowsPowerShell\

2. Create a .ps1 script in this directory called: profile.ps1

3. Inside the profile.ps1, add the following command(s) to call and run in your .ps1 scripts. Obviously, change the script name. I have multiple scripts that contain Authenticate.ps1 at the end of the filename which auto-authenticates me to specific services:

Get-ChildItem C:\Scripts\Powershell\*Authenticate.ps1 | %{. $_ }


Boom.

Advertisement

Add-WindowsCapability : Add-WindowsCapability failed. Error code = 0x800f0954

Scenario: You are trying to install a Windows Capability via PowerShell, such as the AD Tools, however you receive this error: Add-WindowsCapability : Add-WindowsCapability failed. Error code = 0x800f0954

Solution:
On your computer, go to:
1. GPEdit.msc

2. Computer Configuration –> Administrative Templates –> System

3. Open Specify settings for optional component installation and component repair

…4. Select Enabled

…5. Select Download repair content and optional features directly from Windows Update instead of Windows Server Update Services (WSUS)

6. In your Powershell, run gpupdate /force

7. Now, try the install again.

8. Victory! Drink a beer.

Beat your Idle-Timeout on your computer so you do not have to unlock your computer every time you walk your dog.

Scenario: My computer is configured by my organization to lock after its idle for, what feels like, 5 minutes.

Solution: Run this loop in PowerShell.

while (1) {(New-Object -Com "Wscript.Shell").SendKeys("{SCROLLLOCK}{SCROLLLOCK}");Write-Host "`n`n`n`n`n`n`n`ndun dun dun dun--Staying alive. staying alive $(get-date -format MM/dd/yyyy:hh:mm:ss)"; sleep 180}

Pull a list of all Microsoft Licenses and Service Plans for all users

Scenario: You need to pull all licenses assigned to all users in your Azure Online tenant.

Solution: LETS GRAPH IT in PowerShell

#0. Install MSGraph PS Plugin if you dont have it
    Install-Module Microsoft.Graph


#1. Connect to Graph
    Connect-MgGraph -Scopes 'User.Read.All'


#2. Pull all License SKUIDs
    $LicenseSkuID = Get-MgSubscribedSku -All
    $LicenseIndex = Import-csv C:\temp\Microsoft_License_Products.csv #Download the CSV from this site: https://learn.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference



#3. Get list of Users
     $users = Get-MgUser -All


#4. Report it and Loop through users to find licenses
$report = @()
$users | %{

        #Create Variable
        $u = $_.UserPrincipalName

        #Display
        "Pulling licenses for $U"

        #Get license for each user
            [array]$AllLicenses = Get-MgUserLicenseDetail -UserId $u

        #Loop through Licenses
            $AllLicenses | %{
                $SKUID = $_.SkuID
                $SkuPartNumber = $_.SkuPartNumber
                $ServicePlans = $_.ServicePlans
                $Friendly_ProductName = $LicenseIndex | Where GUID -eq $SKUID | Select -ExpandProperty Product_Display_Name -Unique


                If($ServicePlans -ne $null){
                $ServicePlans | %{
                    $AppliesTo = $_.AppliesTo
                    $ProvisioningStatus = $_.provisioningStatus
                    $ServicePlanID = $_.servicePlanID
                    $ServicePlanName = $_.ServicePlanName
                    $Friendly_Name = $LicenseIndex | Where {($_.GUID -eq $SKUID) -and ($_.Service_Plan_Name -eq $ServicePlanName)} | select -ExpandProperty Service_Plans_Included_Friendly_Names

                     $obj = new-object psObject
                        $obj | Add-Member -membertype noteproperty -Name UPN -Value $U
                        $obj | Add-Member -membertype noteproperty -Name SKUID -Value $SKUID
                        $obj | Add-Member -membertype noteproperty -Name SKUPartNumber -Value $SKUPartNumber
                        $obj | Add-Member -membertype noteproperty -Name SKUFriendlyProductName -Value $Friendly_ProductName
                        $obj | Add-Member -membertype noteproperty -Name ServicePlanID -Value $ServicePlanID
                        $obj | Add-Member -membertype noteproperty -Name ServicePlanName -Value $Serviceplanname
                        $obj | Add-Member -membertype noteproperty -Name ServicePlanStatus -Value $ProvisioningStatus
                        $obj | Add-Member -membertype noteproperty -Name ServicePlanAppliesTo -Value $AppliesTo
                        $obj | Add-Member -membertype noteproperty -Name ServicePlanFriendlyName -Value $Friendly_name
                        
                        $report += $obj
                }

                }
}



    }


#5. Display the Report

    $Report

    $Report | Export-csv C:\temp\report.csv

Azure Licenses: License cannot be assigned to a user without a usage location specified.

Scenario: You try to apply a Azure License to a user, but receive this error message: License cannot be assigned to a user without a usage location specified.

Solution: Navigate to the User in Azure, edit the properties, and select the Usage Location.

Check MFA status for users in Azure

Scenario: You need to verify who has MFA configured and how does not. You are interested in knowing which MFA methods users are enrolled into as well.

Scritplet:

#Collect users
    $users = get-msoluser -all



#Loop through all users and store in $Results
$results = @()

 $users | sort userprincipalname | %{
    $n = $_.userprincipalname
    $A= $_.StrongAuthenticationMethods 
    
    If($A -ne $Null){
        Write-Host "$N - Has MFA configured" -ForegroundColor Green
        $A | %{
            $obj = new-object psObject
            $obj | Add-Member -membertype noteproperty -Name UPN -Value $n
            $obj | Add-Member -membertype noteproperty -Name MFAConfigured -Value "Yes"
            $obj | Add-Member -membertype noteproperty -Name IsDefault -Value $_.IsDefault
            $obj | Add-Member -MemberType noteproperty -Name MethodType -Value $_.MethodType
            $Results += $obj
            }
     }else{
        Write-Host "$N - does not have MFA configured" -ForegroundColor Magenta
         $obj = new-object psObject
            $obj | Add-Member -membertype noteproperty -Name UPN -Value $n
            $obj | Add-Member -membertype noteproperty -Name MFAConfigured -Value "No"
            $obj | Add-Member -membertype noteproperty -Name IsDefault -Value "False"
            $obj | Add-Member -MemberType noteproperty -Name MethodType -Value "MFANotConfigured"
            $Results += $obj
            }

     $n = $null
     $a = $null


}

 #View Results
$results 

#Export Results
$results | Export-csv c:\temp\MFAStatus.csv

Locate specific commands, words, or logic in a SEA OF SCRIPTS

Scenario: I have 300 scripts in a directory, but I am not sure which script is running a specific command. Using the following, you can quickly parse through all of your scripts and locate the string ( Command | Word | Phrase ) to see which script has it.

Solution: Scritplet:

$str = "BACKPRESSURE"

get-childitem C:\scripts\*.ps1 -Recurse | Select -ExpandProperty Fullname | %{
        $fn = $_
            $str | %{
                $s = $_
                $D = get-content $fn | Select-String $s
                If($D -ne $Null){
                    Write-Host "
                    Found String in File:  $fn" -ForegroundColor Cyan
                    $D
                    } #ENdIF
            }##end $Str loop
 }#End get-childitem loop

Check for Autodiscover ServiceBindingInformation during the installation of Exchange — This way you can be alerted when the property is configured, and we can $Null it out.

Scenario: We are installing Exchange On-Premises on some new servers, and we want to minimize the amount of Security Alerts that pop up on users Outlook connections. The Security Alerts pop up because we do not put the servername on the public certificates AND Exchange wants to configure the autodiscover record with https://<local server name>/autodiscover/autodiscover.xml — silly Microsoft.

Solution: During the Exchange Installation, run the following scriptlet to loop through and beep/display when it is there, so you can go in and null it out in ADSI edit (or Exchange if it allows you).

#Variables

You can find the exact $AD property by locating the DN of the server by navigating through the ADSIEdit Configuration (working your way backwards from the AD property below) and copying it.

$s = "ExServer21"
$ad = "CN=$s,CN=Autodiscover,CN=Protocols,CN=$S,CN=Servers,CN=Exchange Administrative Group,CN=Administrative Groups,CN=Enterprise Exchange,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domain,DC=com"

#Loop It

Do{
$1 = Get-ADObject $AD -properties * |Select -expandproperty ServiceBindingInformation
"Checking $s for Service Binding Information...."
If($1 -ne $null){ 
    [console]::beep(500,300)
    "ServiceBindingInfomation: $1"}
Sleep 5
}While($C -ne "RunForever")

You could also run set-clientaccessserver <servername> -AutodiscoverServiceInternalUri $null



Scriptlets to check Recent Windows and Exchange updates/patches

Scenario: You have just updated your Exchange Servers (or Windows Servers) and you want to verify the successful install of the patches through logic.

Solution: SCRIPTLETS:

#Pull a list of Servers
   $Servers = get-exchangeserver |sort name| Select -ExpandProperty Name 
   #-or-
   $servers = "ExServer1","ExServer2"
    
#Pull Updates
   $Ex_Updates = @(); $servers | %{$n = $_; "Checking Exchange File for $n"; $Ex_Updates+= Invoke-Command -ComputerName $n -ScriptBlock {GCM exsetup |%{$_.Fileversioninfo}}}
   
   $Win_Updates = @(); $servers | %{$n = $_; "Checking Windows Updates for $n"; $Win_Updates+= Get-HotFix -ComputerName $n |Where InstalledOn -ge (get-date).AddDays(-7) | Select @{Name="Server";Expression={$n}}, Description, HotFixID, InstalledOn }
    
#Display variables of updates
    $Ex_updates 
    $Win_Updates

    #Note: You can group to make it easier to quickly identify everything looks right
    $Win_Updates |Group Hotfixid
      
    $Win_Updates |Group server 

Windows – Unable to join domain. “An account with the same name exists in Active Directory. Re-using the account was blocked by security policy”

Scenario: The error below was received when joining a new computer to a domain (the computer object was pre-staged in AD by creating the computer object and resetting it).

Error: “An account with the same name exists in Active Directory. Re-using the account was blocked by security policy”

Solution: Add the following Reg Key:

Reg add HKLM\System\CurrentControlSet\Control\Lsa /v NetJoinLegacyAccountReuse /t REG_DWORD /d 1 /f