MSTeams: Get-CsOnlineUser – Clean Output (PowerShell)

There are many more user attributes emitted in the call to Get-CsOnlineUser in Microsoft Teams compared to that of Skype for Business Server (Get-CsUser).

Rather than having to always visually inspect each and every entry, consider using the following to filter to those with value of interest only i.e. skip those with no values (null or empty):

########## MSTeams: Get-CsOnlineUser - ' Clean ' Output (PowerShell)
#Copyright (c) All Rights Reserved
#www.leedesmond.com 
#2023-02-06 Version: 1.0

#Connect-MicrosoftTeams;

$samAccountName="desmond";
$umst=Get-CsOnlineUser $samAccountName;
$umstNoteProperty=($umst|Get-Member -MemberType NoteProperty).Name;

$attributes=@();
$umstNoteProperty|%{
     if(![string]::IsNullOrEmpty($umst.$PsItem)){
          #"$($_): $($umst.$_)";
          $attributes+=[pscustomobject]@{name=$_;value=$umst.$_;}
     }
}
#attributes|Format-Table -Autosize;

MSTeams: Policy Packages – Manage with PowerShell

########## MSTeams: Policy Packages - Manage with PowerShell
#Dump details (assigned policies) of MS Teams policy packages
#Copyright (c) All Rights Reserved
#www.leedesmond.com 
#2023-02-03 Version: 1.0

Connect-MicrosoftTeams
$ppc=$pp=Get-CsPolicyPackage

#optionally apply filter to customised policy packages only
#Note: limited to MS Teams Premium licensees
$ppc=$pp|Where-Object PackageType -eq 'Custom';

$ppc|%{
     Write-Verbose "$($PsItem.Name)`n$($PsItem.Description)"-Verbose;
     $_i=$PsItem;
     $_i.policies.keys|%{
          Write-Host "$($PsItem)//$($_i.policies[$PsItem].values)";
          $_i.policies[$PsItem].values|%{$_};
     }
}

PowerShell: Upgrade from Azure AD PowerShell to Microsoft Graph PowerShell

Windows PowerShellFor those who still have not embarked on a plan to migrate to Microsoft Graph PowerShell SDK in order to automate and manage their Microsoft 365 tenant:

” Microsoft Graph PowerShell is the replacement for the Azure AD PowerShell and MSOnline modules and is recommended for interacting with Azure AD.

Azure AD, Azure AD Preview and MSOnline PowerShell modules are planned for deprecation. Microsoft Graph PowerShell is the PowerShell module to use for interacting with Azure AD and other Microsoft services.
… ” [1]

REFERENCES
Microsoft Graph PowerShell v2 is now in public preview, half the size and speeds up automation

[1] Upgrade from Azure AD PowerShell to Microsoft Graph PowerShell

PowerShell: What is My Chinese Zodiac Sign?

恭喜發財 。身體健康
Kung Hei Fat Choi*
Happy, Healthy & Prosperous Lunar Chinese New Year
(of the Rabbit)

農曆新兔年 大年初一 (2023-01-22)

########## PowerShell: What is My Chinese Zodiac Sign
#Copyright (c) All Rights Reserved 農曆新兔年 Lunar Chinese New Year of Rabbit 
#www.leedesmond.com 
#2023-01-22 Version: 1.0

param(
$MyBirthYear=(Get-Date).Year,[switch]$IncludeOutput
) 
$author ="www.leedesmond.com"; 
$scriptName="What_is_my_Chinese_Zodiac_Sign.ps1"; 
$date="2023-01-22"; 
$version="1.0";

function GetChineseZodiac()
{
param([int]$ref=1924,[int]$gap=12,$BirthYear)

[hashtable]$ChineseZodiac=[ordered]@{}; 
# 
$ChineseZodiac[1924]=[PSCustomObject]@{Year=-1;SignZmt="鼠";SignJyutPing="syu2"  ;Sign="Rat"    } #, 1936, 1948, 1960, 1972, 1984, 1996, 2008, 2020 
$ChineseZodiac[1925]=[PSCustomObject]@{Year=-1;SignZmt="牛";SignJyutPing="ngau4" ;Sign="Ox"     } #, 1937, 1949, 1961, 1973, 1985, 1997, 2009, 2021 
$ChineseZodiac[1926]=[PSCustomObject]@{Year=-1;SignZmt="虎";SignJyutPing="fu2"   ;Sign="Tiger"  } #, 1938, 1950, 1962, 1974, 1986, 1998, 2010, 2022 
$ChineseZodiac[1927]=[PSCustomObject]@{Year=-1;SignZmt="兎";SignJyutPing="tou3"  ;Sign="Rabbit" } #, 1939, 1951, 1963, 1975, 1987, 1999, 2011, 2023 
$ChineseZodiac[1928]=[PSCustomObject]@{Year=-1;SignZmt="龍";SignJyutPing="lung4" ;Sign="Dragon" } #, 1940, 1952, 1964, 1976, 1988, 2000, 2012, 2024 
$ChineseZodiac[1929]=[PSCustomObject]@{Year=-1;SignZmt="蛇";SignJyutPing="se4"   ;Sign="Snake"  } #, 1941, 1953, 1965, 1977, 1989, 2001, 2013, 2025 
$ChineseZodiac[1930]=[PSCustomObject]@{Year=-1;SignZmt="馬";SignJyutPing="maa5"  ;Sign="Horse"  } #, 1942, 1954, 1966, 1978, 1990, 2002, 2014, 2026 
$ChineseZodiac[1931]=[PSCustomObject]@{Year=-1;SignZmt="羊";SignJyutPing="joeng4";Sign="Goat"   } #, 1943, 1955, 1967, 1979, 1991, 2003, 2015, 2027 
$ChineseZodiac[1932]=[PSCustomObject]@{Year=-1;SignZmt="猴";SignJyutPing="hau4"  ;Sign="Monkey" } #, 1944, 1956, 1968, 1980, 1992, 2004, 2016, 2028 
$ChineseZodiac[1933]=[PSCustomObject]@{Year=-1;SignZmt="雞";SignJyutPing="gai1"  ;Sign="Rooster"} #, 1945, 1957, 1969, 1981, 1993, 2005, 2017, 2029 
$ChineseZodiac[1934]=[PSCustomObject]@{Year=-1;SignZmt="狗";SignJyutPing="gau2"  ;Sign="Dog"    } #, 1946, 1958, 1970, 1982, 1994, 2006, 2018, 2030 
$ChineseZodiac[1935]=[PSCustomObject]@{Year=-1;SignZmt="豬";SignJyutPing="zyu1"  ;Sign="Pig"    } #, 1947, 1959, 1971, 1983, 1995, 2007, 2019, 2031 

#calculate Chinese Zodiac year 
$result =$ref..($ref+11) | ? { $($BirthYear-$PSItem)%$gap -eq 0 } 
$result1=$ChineseZodiac[$result]; 
$result1.Year=$BirthYear; 

Write-Output $result1; 
} 

Write-Verbose "Script : $scriptName" -Verbose; 
Write-Verbose "Author : $author" -Verbose; 
Write-Verbose "Version: $date v$version" -Verbose; 

$result=GetChineseZodiac -BirthYear $MyBirthYear; 

Write-Verbose $($result|Out-String) -Verbose; 
if($IncludeOutput){Write-Output $result;} 

Write-Verbose "SignZmt=Traditional Chinese" -Verbose; 
Write-Verbose "SignJyutPing=粵拼 (jyut6 ping3) Cantonese romanization system (https://jyutping.org/)" -Verbose; 
Write-Verbose "" -Verbose;

#powershell #農曆新年 #兔年 #粵語

* gung1 hei2 faat3 coi4
(#粵拼 #JyutPing #Cantonese romanization systems)

PowerShell: Unattended key press (simulate not away presence status “mouse jiggle”)

########## PowerShell: Unattended key press
#simulate not away presence status available "mouse jiggle" or wiggle
#Copyright (c) All Rights Reserved
#www.leedesmond.com 
#2023-01-15 Version: 1.0

param($IntervalInSeconds=15,
    [string[]]$Keys=@('+{F15}','+{F14}','+{F13}'),[switch]$NoNewline)

function SimulateKeyPress()
{
param($IntervalInSeconds,[string[]]$Keys,[switch]$NoNewline)
    if($IntervalInSeconds -is [string] -or $IntervalInSeconds -le 0){ #-or $IntervalInSeconds -isnot [int] 
        Write-Host "Usage: script.ps1 -IntervalInSeconds N  #where N > 0";
        return;}
    $dateStart=Get-Date; $elapsed="00:00:00";
    Write-Host "Start: $dateStart";
    $wsh=New-Object -ComObject WScript.Shell;
    $KeysLen=$Keys.Length-1;
    while($IntervalInSeconds -gt 0){
        $index=Get-Random -Minimum 0 -Maximum $KeysLen;
        $wsh.SendKeys($Keys[$index]);
        #$logonUI=$false;
        try{Get-Process LogonUI -EA:Stop|Out-Null;$logonUI=$true;}catch{$logonUI=$false;}
        Write-Host `
            "($((Get-Date).ToString()) elapsed: $elapsed key: $($Keys[$index]) " `
            "IntervalInSeconds: $IntervalInSeconds LogonUI: $logonUI) " `
            -NoNewline:$NoNewline;
        Start-Sleep -Seconds $IntervalInSeconds;
        $dateNow=Get-Date;
        $elapsed=$dateNow-$dateStart;
        $elapsed="{0:d2}:{1:d2}:{2:d2}" -f $elapsed.Hours,$elapsed.Minutes,$elapsed.Seconds;
    }
} #SimulateKeyPress()

SimulateKeyPress -IntervalInSeconds $IntervalInSeconds -Keys $Keys -NoNewline:$NoNewline;

PowerShell: AzureAD vs. AzureADPreview Modules

Windows PowerShellAs of today, the current versions of the AzureAD and AzureADPreview PowerShell modules stand at 2.0.2.140 (2021-08-19) and 2.0.2.149 (2022-02-01) respectively.

This means that a number of useful cmdlets such as Get-AzureADPolicy and Get-AzureADDirectorySetting  will trigger similar errors as follows if the preview module is not installed and/or loaded via Import-Module in your (production) environment:

Get-AzureADDirectorySetting : The term ‘Get-AzureADDirectorySetting’ is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.
At line:1 char:1
+ Get-AzureADDirectorySetting
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-AzureADDirectorySetting:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException