April 30, 2025

April 21, 2025 | Dan

Automate FTP with PowerShell

Automate FTP with PowerShell

Automate FTP with PowerShell 

So, you want to Automate FTP with PowerShell? Well, you have come to the right place. FTP is not dead . In fact, it is still quite widely used. If all you need is files to be transferred from one place to another, it is the best choice. 

Why would you need to Automate FTP with PowerShell 

There are several reasons you would need to automate FTP with PowerShell. One is compatibility. Batch files are still around but to get them to automate FTP, you must call on third party programs that may or may not be kept up to date. As OSes start to update the third party application may fall behind. This leads me to my second point…. 

Security with PowerShell 

You can be more granular with security and PowerShell. It is baked into M365 and local AD so you can be sure that only the users you require can run the script to Automate FTP with PowerShell. 

Prerequisites to the Script 

You will need the following before you can run the script to Automate FTP with PowerShell. 

WinSCP Automation 

The script calls on WinSCP FTP Automation to load a DLL so it can connect to your required FTP Server and transfer files. You need to register the DLL in the Directory it is going to be called from. The documentation is a bit confusing but simply put, extract the DLL to the same folder as the script. Then drop to CMD prompt and navigate to that folder and then register the DLL: 

%WINDIR%\Microsoft.NET\Framework64\<version>\RegAsm.exe WinSCPnet.dll /codebase /tlb 

Make sure the version of .NET you are using is specified in <version>. I used v4.0.30319 

So, my command looked like this: 

%WINDIR%\Microsoft.NET\Framework64 v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb 

If Running the Script on a Server 

You need to make sure the Above DLL is registered for the user account running the script. You also need Full Control file security on the folder that houses the script. The reason for this is you need to be able to rename and move files in and around the file structure which otherwise require admin access. Without this, the script will not run. 

If Connecting to SFTP 

You will need to get the SSHHost Key If connecting with a password or both the SSHHost Key and SSHKeyPath file (if not using a password) and point to where it is stored (Preferable in the same folder as everything else). 

But if you connect manually to these servers, you already have this information. If not, reach out to the vendor or organization you need to connect to. My example only needs the SSH Host Key. 

Bonus: If You Plan to Notify of Completion or Errors via Email 

If you plan To Send Mail In PowerShell , you will need to create an App Registration in Entra with the correct permission to send mail and then have that account give consent to allow it to be used to send mail through API (like PowerShell). I have written an article about it. You should check it out. It will help Automate FTP with PowerShell. 

The Script 

This is an example of a PowerShell Script to Automate FTP with PowerShell by downloading a file, renaming it and then moving it: 

try 

    # Load WinSCP .NET assembly 

    Add-Type -Path “C:\Path\To\WinSCP\Automation\WinSCPnet.dll”  ## https://winscp.net/download/WinSCP-5.19.6-Automation.zip 

    # Setup session options 

    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ 

        Protocol = [WinSCP.Protocol]::Sftp # Port 22 Sftp | FTP Port: 21 

        HostName = “<ip address>” #IP TO FTP/SFTP 

        UserName = “<username>” #USERNAME 

        Password = <password>!”  #PASSWORD LEAVE EMPTY IF YOU USE PRIVATE KEY LIKE THIS( Password = “” ) 

        SshHostKeyFingerprint = “ssh-ed25519 255 UINj1Jc5jKcADtEwF0dd0tUjjk4KNp3JN6EyQf5G7ns” 

        #SshPrivateKeyPath= “C:\Users\Admin\private.ppk” #If you use password make “SshPrivateKeyPath” to a comment or delete the line! 

    } 

    $session = New-Object WinSCP.Session 

    try 

    { 

        # Connect 

        $session.Open($sessionOptions) 

        $transferOptions = New-Object WinSCP.TransferOptions 

        $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary 

        $transferResult = 

            $session.GetFiles(“/incoming/Sample.csv”, “C:\Path\To\File\Upload\”, $False, $transferOptions) #Get files from incoming to upload 

            # Use $session.PutFiles(LocalPath, RemotePath) instead If you are wanting to send files to the SFTP/FTP Server. 

        # Throw on any error 

        $transferResult.Check() 

        # Print results 

        foreach ($transfer in $transferResult.Transfers) 

        { 

           Write-Host “Download of $($transfer.FileName) to $localPath succeeded” 

           $transferResult.Transfers      

        } 

    } 

    finally 

    { 

        # Disconnect, clean up (Session.Close to exit the session!) 

        $session.Close()         

    } 

    #exit 0 

catch 

    Write-Host “Error: $($_.Exception.Message)” 

    .\NotifyMailFailed.ps1 

    exit 1 

$Exist = Test-Path “C:\Path\To\File\Upload\”, Sample.csv” -PathType Leaf 

$IsTrue = $Exist 

if ($IsTrue) { 

# rename file and move to Archive Folder 

# Write file is there 

$time = Get-Date -Format “MM-dd-yyyy” 

Rename-Item -Path ” C:\Path\To\File\Upload\Sample.csv” -NewName Sample_$time.CSV 

Move-Item -Path ” C:\Path\To\File\Upload\*.csv”  -Destination ” C:\Path\To\File\Upload\saved” 

## Notifying Via Email Upload is Complete 

#refer to https://www.cayville.ca/the-correct-way-to-send-mail-in-powershell/ 

.\NotifyMail.ps1 

} else { 

# Write file is NOT there 

## Notifying Via Email Upload is Complete 

#refer to https://www.cayville.ca/the-correct-way-to-send-mail-in-powershell/ 

.\NotifyMailFailed.ps1 

}  

Benefits When You Automate FTP with PowerShell 

When you can automate any process that is normally done manually, it is a benefit. It saves you time from performing several steps and concentrates on what you need to do most. Probably analyzing the data (Not retrieving it)! 

Another Benefit is if you must automate several FTP services all you have to do is copy the script and change the particulars. You will be up and running in no time 😊 

Share: Facebook Twitter Linkedin
April 15, 2025 | Dan

A Simple Script for M365 Licenses 

You need to juggle M365 Licenses, but you need to see who has them first? It seems simple, it is, and you can write a Script for M365 Licenses, but you will need to do a little preparation first. 

Why Would you Need a Script for M365 Licenses 

That is a very good question. A good example is that you are switch licensing vendors and you would like to see how many licenses you need to switch out. Once you know who has this license you can get a list and then switch them out. 

I can give you a piece of advice. Add new licenses first and make sure they work before you remove the old licenses! Even if the old licenses sit expired, the new ones must be added first. I will write an article in the future of what happens if you do it backwards LOL. 

A script for M365 licenses will help with this. 

What you Need to Write the Script 

You will need 4 Things. 

  1. A csv file with the group of users you would like to check. This CSV will include three columns labelled UPName, DisplayName and Object ID 
  1. The SKU ID of the Microsoft product you want to Check 
  1. A PowerShell script to check the SKU 
  1. A PowerShell script to deal with the SKU (in this case, remove) 

Create a CSV for Your Script for M365 Licenses 

This is an example CSV that you would use for your script. Name it Sample.csv so it is the same file that is referenced in the script.

To get this information, you will need to go to your Entra Portal and under all users, click download users:

You can use this info to create your sample.csv.

Get the SKU ID of the M365 License you Want to Query 

You will need to connect to Microsoft Graph and run the command Get-MgSubscribedSku: 

Connect-Graph -Scopes Organization.Read.All 

Get-MgSubscribedSku | Select -Property Sku*, ConsumedUnits -ExpandProperty PrepaidUnits | Format-List  

You will get a listing of all licensed products in your tenant. From there you can get the SkuId: 

SkuId : 06ebc4ee-1bb5-47dd-8120-11324bc54e06 

SkuPartNumber : SPE_E5 

In this example, we are querying the SkuID for the now discontinued E5 licensing. It has been happening for awhile but it might be hitting you now because your current agreement needs to be renewed. You will now need to copy the ID into a Script for M365 Licenses. Now that you have your CSV and License to query, it is now time for the Script for M365 Licenses. 

Script to Check for the SKU 

# Connect to Microsoft 365 

Connect-MgGraph -Scopes User.Read.All, Organization.Read.All 

 
#Path to UPN File # 


$CSVPathUPN = ".\sample.csv" 


##Run Script## 

 
##Try import UPN CSV file## 


Write-Host Importing CSV 


try { 

    $UPNUsers = import-csv $CSVPathUPN -ErrorAction stop 
} 

catch { 

    throw "Error importing CSV: $($_.Exception.Message)" 

    break 

} 


foreach ($UPNUser in $UPNUsers) { 

 

$Uname = $UPNUser.UPName 

$Dname = $UPNUser.displayName 

$ObjID = $UPNUser.ObjectID 


# Checks if they have SPE5 


# Define the license SKU you're checking for (e.g., "E5" or the SKU ID) 

$Sku = "06ebc4ee-1bb5-47dd-8120-11324bc54e06" 

 
# Get the user's license details 

$CurrentLicenses = Get-MgUserLicenseDetail -UserId $Uname | Select-Object -ExpandProperty SkuId 

 

# Check if the specified license is assigned 

if ($Sku -in $CurrentLicenses) { 

    Write-Host "User '$Dname' has license: $Sku" 

} else { 

    Write-Host "User '$Dname does not have license: $Sku" 

} 

 

} 

Write-Host All done 



The script will cycle through each user and tell you whether that user has that license. 
 

Script to Remove for the SKU 

Now that you know which user(s) have the licenses, you can compile your CSV above and run the following script to remove the them: 


##Connect to Azure and MSGraph modules## 

Connect-MgGraph -Scopes User.ReadWrite.All, Organization.Read.All 

 

#Path to UPN File # 

 

$CSVPathUPN = ".\sample.csv" 

 

##Run Script## 

 

##Try import UPN CSV file## 

 

Write-Host Importing CSV 

 

try { 

    $UPNUsers = import-csv $CSVPathUPN -ErrorAction stop 

} 

catch { 

    throw "Error importing CSV: $($_.Exception.Message)" 

    break 

} 

 

$f1Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' 

 

foreach ($UPNUser in $UPNUsers) { 

 

$Uname = $UPNUser.UPName 

$Dname = $UPNUser.displayName 

$ObjID = $UPNUser.ObjectID 

 

# Remove SPE5 

 

Set-MgUserLicense -UserId $Uname -RemoveLicenses @($f1Sku.SkuId) -AddLicenses @() -ErrorAction Stop 

 

Write-Host Remove Legacy E5 Licensing for $Dname .... 

 

} 

 

Write-Host All done

This is a good way to write a Script for M365 Licenses!

Share: Facebook Twitter Linkedin
April 8, 2025 | Dan

Managing Calendar Permissions with PowerShell

Calendar Permissions with PowerShell

Managing calendar permissions with PowerShell on Microsoft 365 / Exchange Online will often require you to use PowerShell a bit. I can explain how to perform typical day-to-day admin tasks involving calendar permissions, using PowerShell.

Before managing permissions, you need to connect to Exchange Online through PowerShell. Once connected, you can view existing calendar permissions, add new permissions, edit existing calendar permissions, and remove calendar permissions.

Connect to Exchange Online via PowerShell

Connecting to Exchange Online via PowerShell requires just a few commands. Follow the instructions below to connect to Exchange Online from your PowerShell prompt.

  • Launch PowerShell from Workstation
  • Run the Following Four Commands in Order:
Set-ExecutionPolicy RemoteSigned -Force
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session

The above script will prompt you for O365 credentials. When prompted, supply your credentials for the O365 tenant you are trying to manage.

If you know how to use PowerShell, you can easily write a script to automate this.

Viewing Calendar Permissions with PowerShell

Before setting / updating / removing permissions from an O365 calendar, it is a good idea to see what permissions currently exist on it so they can be set back to their original permissions if you make a mistake. To list the permissions on a calendar using PowerShell, run the Get-MailboxFolderPermission command in PowerShell after you have connected to Exchange Online.

Get-MailboxFolderPermission -Identity <[email protected]>:\Calendar

You would obviously replace [email protected] with the user whose calendar permissions you want to view. If you prefer, you can pipe the output to a CSV file as well by appending | Export-CSV c:\filepath\filename.csv to the command:

Get-MailboxFolderPermission -Identity <[email protected]>:\Calendar | Export-CSV c:\filepath\filename.csv

Replace filepath with the path to the file you are creating and filename with the name you want to give the CSV file.

Removing Calendar Permissions with PowerShell

Removing existing permissions from a calendar in O365 with PowerShell requires just a single command (Remove-MailboxFolderPermission). To run it, make sure you have connected to Exchange Online via PowerShell and then run the command below. In the example below, we are removing John’s access from Jen’s calendar:

Remove-MailboxFolderPermission -Identity <[email protected]>:\Calendar -User [email protected]

Adding Permissions to a Calendar with PowerShell

The Add-MailboxFolderpermission PowerShell command is used to add permissions to a calendar. You can only ADD permissions to a calendar for a user if there are not already permissions configured. If you need to UPDATE permissions that already exist, you would use the Set-MailboxFolderPermission command.

To clarify, let’s use the following example:

Jimmy is a new hire at Contoso. He has not yet been given any permissions to User’s calendar and now needs “Reviewer” access. Since he currently has no permissions to Jen’s calendar, you would use the command below to add his permissions to Jen’s calendar:

Add-MailboxFolderPermission -Identity <[email protected]>:\calendar -user <[email protected]> -AccessRights Reviewer

If Jimmy already had permissions (i.e. Editor, Author, etc) to User’s calendar, running the Add-MailboxFolderPermission command would have generated an error indicating permissions already exist. In that case, you would use the Set-MailboxFolderPermission command instead (see below).

Changing Permissions on a Calendar in O365 with PowerShell

Changing permissions that already exist on the calendar in O365 requires a different command. Instead of running the Add-MailboxFolderPermission PowerShell command, you should run the Set-MailboxFolderPermission command when you need to update pre-existing permissions.

For example, if John already has Reviewer access to Jen’s calendar, you will use the command below to change the permissions to Editor:

Set-MailboxFolderPermission -Identity [email protected]:\Calendar -User jimmy@ company.com -AccessRights Editor

If you try to run the command above, it will fail if existing permissions are not already in place.

Available Calendar Permissions with PowerShell

There are 10 available roles that you can set on calendars. They are:

  • Owner.  Allows read, create, modify and delete all items and folders. Also allows managing items permissions
  • PublishingEditor.  Allows read, create, modify and delete items/subfolders.
  • Editor.  Allows read, create, modify and delete items.
  • PublishingAuthor.  Allows read, create all items/subfolders. You can modify and delete only items you create.
  • Author.  Allows create and read items; edit and delete own items.
  • NonEditingAuthor.  Allows full read access and create items. You can delete only your own items.
  • Reviewer.  Read only.
  • Contributor.  Allows create items and folders.
  • AvailabilityOnly.  Allows read free/busy information from calendar
  • LimitedDetails.  Allows view of the subject and location.
  • None.  No permission to access folder and files.

You may use any of the above roles when setting permissions on calendars in O365 with PowerShell.

Summary or Calendar Permissions with PowerShell

Managing calendars in M365 with PowerShell requires familiarity with four commands:

The Get-MailboxFolderPermission command is used to view existing permissions.

The Remove-MailboxFolderPermission is used to remove existing permissions. 

Add-MailboxFolderPermission is used to add NEW permissions to a calendar and

Set-MailboxFolderPermission is used to modify EXISTING permissions on the calendar.

Share: Facebook Twitter Linkedin