Category Archives: Automation

ODBC SQL driver error

If you know how to clear the ODBC Driver 17’s token cache, please comment 🙂


Ran into the following error today and putting it here for searches as literally nothing came up:

Run-time error '-2147467259 (80004005)':
[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]User option must be specified, if Authentication option is 'ActiveDirectoryInteractive'.

This was through an excel Macro, connecting to an Azure PaaS database. All other users were just getting prompted, but one kept having this issue.

We managed to ‘solve’ the issue by going into the macro properties and adding User ID=xxx@xxx.com to the connection string where xxx@xxx.com was the user’s actual UPN.

Unsharing Orphaned Onedrive for Business sites with active sharing links

When a user leaves the organization, their Onedrive folders/files remain until either the user is permanently deleted or the retention policy covering their data expires.

Many organizations have set up a retention policy in Office 365 to retain data in Onedrive for several years, sometimes even indefinitely.

Few know, that as long as you retain a user’s onedrive, the files and folders that were shared, by default, remain shared and accessible by those they were shared with, including externals.

This is often undesirable, and can easily be remediated by running a very simple unshare-orphanedOnedriveForBusinessSites.ps1 PowerShell function I’m hereby sharing with you 🙂

Above function detects all Onedrive Sites that no longer have an active associated user, and disables any sharing links on them.

The actual line that unshares an individual site could also be used directly if you have an automatic offboarding process.

(re) configuring hidden VPN Profile properties

Using MEM (Intune) we can automatically deploy VPN profiles to our users’ managed devices directly.

The set of parameters that can be configured in MEM is extremely limited compared to what actually ends up on the rasphone.pbk file (VPN Profile) on a Windows client.

Example of a .pbk file for an Azure P2S VPN connection with Conditional Access/cert based SSO:

[AzureVirtualNetwork]
Encoding=1
PBVersion=6
Type=4
AutoLogon=0
UseRasCredentials=1
LowDateTime=-1117351264
HighDateTime=30942358
DialParamsUID=927022140
Guid=AABC7C8342FD91458105A961BE471F8E
VpnStrategy=7
ExcludedProtocols=8
LcpExtensions=1
DataEncryption=256
SwCompression=1
NegotiateMultilinkAlways=1
SkipDoubleDialDialog=0
DialMode=0
OverridePref=15
RedialAttempts=0
RedialSeconds=0
IdleDisconnectSeconds=0
RedialOnLinkFailure=0
CallbackMode=0
CustomDialDll=
CustomDialFunc=
CustomRasDialDll=%windir%\system32\cmdial32.dll
ForceSecureCompartment=0
DisableIKENameEkuCheck=0
AuthenticateServer=0
ShareMsFilePrint=1
BindMsNetClient=1
SharedPhoneNumbers=0
GlobalDeviceSettings=0
PrerequisiteEntry=
PrerequisitePbk=
PreferredPort=VPN2-0
PreferredDevice=WAN Miniport (IKEv2)
PreferredBps=0
PreferredHwFlow=0
PreferredProtocol=0
PreferredCompression=0
PreferredSpeaker=0
PreferredMdmProtocol=0
PreviewUserPw=0
PreviewDomain=0
PreviewPhoneNumber=0
ShowDialingProgress=0
ShowMonitorIconInTaskBar=1
CustomAuthKey=13
CustomAuthData=314442430D000405C000000020005005C0000001500000014000000A8985D3A65E5E5C4B2D7D66D40C6DD2FB19C5436020001001230FE0006000100FCD02C00
CustomAuthData=3BCB684FDAE6ED1B763A3EDEB989B12C95EFFAFFD330281E75F1C671B03CDD800FF0844797977764005000500
AuthRestrictions=128
IpPrioritizeRemote=0
IpInterfaceMetric=1
IpHeaderCompression=1
IpAddress=0.0.0.0
IpDnsAddress=172.1.230.4
IpDns2Address=172.1.230.5
IpWinsAddress=0.0.0.0
IpWins2Address=0.0.0.0
IpAssign=1
IpNameAssign=2
IpDnsFlags=0
IpNBTFlags=1
TcpWindowSize=0
UseFlags=2
IpSecFlags=0
IpDnsSuffix=
Ipv6Assign=1
Ipv6Address=::
Ipv6PrefixLength=0
Ipv6PrioritizeRemote=1
Ipv6InterfaceMetric=0
Ipv6NameAssign=1
Ipv6DnsAddress=::
Ipv6Dns2Address=::
Ipv6Prefix=0000000000000000
Ipv6InterfaceId=0000000000000000
DisableClassBasedDefaultRoute=1
DisableMobility=0
NetworkOutageTime=0
IDI=
IDR=
ImsConfig=0
IdiType=0
IdrType=0
ProvisionType=0
PreSharedKey=
CacheCredentials=0
NumCustomPolicy=0
NumEku=0
UseMachineRootCert=0
Disable_IKEv2_Fragmentation=0
PlumbIKEv2TSAsRoutes=0
NumServers=0
RouteVersion=1
NumRoutes=0
NumNrptRules=0
AutoTiggerCapable=0
NumAppIds=0
NumClassicAppIds=0
SecurityDescriptor=
ApnInfoProviderId=
ApnInfoUsername=
ApnInfoPassword=
ApnInfoAccessPoint=
ApnInfoAuthentication=1
ApnInfoCompression=0
DeviceComplianceEnabled=0
DeviceComplianceSsoEnabled=0
DeviceComplianceSsoEku=
DeviceComplianceSsoIssuer=
WebAuthEnabled=0
WebAuthClientId=
FlagsSet=0
Options=0
DisableDefaultDnsSuffixes=0
NumTrustedNetworks=0
NumDnsSearchSuffixes=0
PowershellCreatedProfile=0
ProxyFlags=0
ProxySettingsModified=0
ProvisioningAuthority=
AuthTypeOTP=0
GREKeyDefined=0
NumPerAppTrafficFilters=0
AlwaysOnCapable=0
DeviceTunnel=0
PrivateNetwork=0

NETCOMPONENTS=
ms_msclient=1
ms_server=1

MEDIA=rastapi
Port=VPN2-0
Device=WAN Miniport (IKEv2)

DEVICE=vpn
PhoneNumber=azuregateway-12341ef-4922-4edc-a492-589b3e547c58-1ba19cb9ae52.vpn.azure.com
AreaCode=
CountryCode=0
CountryID=0
UseDialingRules=0
Comment=
FriendlyName=
LastSelectedPhone=0
PromoteAlternates=0
TryNextAlternateOnFail=1

Modifying VPN Profile settings

To allow admins further customization of these settings, I’ve written a Proactive Remediation script that can customize any VPN profile property to any value you specify.

In our case, we used it to set IpInterfaceMetric, which defaults to 0, causing ambiguously routed traffic to never prefer the VPN connection (since this is a split tunnel connection). Setting it to 1 resolved our DNS/routing issues to certain private endpoints in our Azure environment.

Code / git link: https://gitlab.com/Lieben/assortedFunctions/-/blob/master/set-vpnConnectionInterfaceMetric.ps1

Automated Stale Device Cleanup in Azure Active Directory using a runbook

As with cleaning up inactive guest users, inactive devices also pose several issues for organizations.

Microsoft recommends cleaning up stale devices after 90 days, but does not provide a service option or automation to do so.

Therefore, here’s another runbook you may run to just report on your inactive devices, or to automatically (and optionally periodically) clean up inactive devices in your environment when the removeInactiveDevices switch is supplied.

Managed identity

When run locally, interactive sign in is required. When running as a runbook in Azure automation, the Managed Identity of the automation account is leveraged. This requires you to set Device.ReadWrite.All or Device.Read.All permissions depending on if you want to script to do the cleanup as well.

Autopilot / on premises devices

Note that the script will log an error (and not attempt to delete the device) when a device is an autopilot record (not a real device) or when the device is synced from an on-premises active directory.

Disable vs Delete

The runbook also has a disable option, in which it will first disable a device and wait a configurable ($disableDurationInDays) period of time before actually deleting a device.

Reports

If you wish, you can also let the script mail you a report in CSV format. Add the Mail.Send graph permissions like you did with device permissions and give the MailFrom and MailTo parameters a value.

Download

Download get-AzureADInactiveDevices.ps1 from Gitlab

Disclaimer

As always, the script is provided as-is and should be reviewed and then used at your own risk.

Guest User Last Sign-in date time in Azure Active Directory and automatic cleanup

Azure AD’s sign in logs also only go back 30 days, which makes it highly recommended to stream Azure AD’s sign in logs to a Log Analytics workspace (Azure Monitor). You just need one single P1 license in your tenant to be able to enable this.

However, even if you don’t stream your sign in logs, Microsoft does keep track of when an account last signed in.

My script gets the last sign in data of all guest accounts in your tenant, without any dependencies other than the Az PS module.

If a guest user has never signed in, the creationDate is used to determine inactivity. Otherwise either the last interactive or last non interactive sign in is used (whichever is most recent).

Additionally, the script can also be configured to automatically clean up any guest accounts that have been inactive for a given number of days by using the -removeInactiveGuests switch.

Even in large environments, processing only takes a few minutes at most.

Download

Download the script from my Gitlab here:

https://gitlab.com/Lieben/assortedFunctions/-/blob/master/get-AzureAdInactiveGuestUsers.ps1

Limitations

Microsoft started using these properties in april 2020, so accounts active before that will seem like they have never been active.

Scheduling

This script supports running non-interactive as a runbook in Azure Automation if you supply the -nonInteractive switch. Before this will work, you’ll have to enable Managed Identity on your automation account and run a small script to assign graph permissions to the Managed Identity: AuditLog.Read.All and Organization.Read.All

Reports

If you wish, you can also let the script mail you a report in CSV format. Add the Mail.Send graph permissions like you did with device permissions and give the MailFrom and MailTo parameters a value.

Disclaimer

As always this script is provided as-is and should be reviewed and then used at your own risk.