├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── Active Directory ├── ADSite.ps1 ├── Copy-AD-Group-Members.ps1 ├── Elevated-Rights.ps1 ├── Install_ActiveDirectory_DomainController.ps1 ├── README.md ├── Set-ADAccountExpirationfromCSV.ps1 └── Set-ADSitetoComputerLocationField.ps1 ├── ConfigMgr ├── Connect-SCCM.ps1 ├── Create-UserDeviceCollections.ps1 ├── Invoke-SCCM-ApplicationEval.ps1 └── README.md ├── DSC ├── Linux │ ├── ApacheUbuntuDSC.ps1 │ └── DSCLinuxPush.ps1 └── Windows │ ├── CitrixVDA.ps1 │ ├── InstallWindowsAdminCenter_DSC.ps1 │ ├── StopBITS.ps1 │ ├── Windows10_Hardening.ps1 │ └── WindowsServer2016_Hardening.ps1 ├── Desktop ├── Check-MicTrayExist.ps1 ├── Clean-AppVClientPackage.ps1 ├── Enable-OneDriveSyncReport.ps1 ├── Go-HomeReminder.ps1 ├── README.md ├── Redirect-Desktop.ps1 ├── Set-OEMInfo.ps1 ├── Set-PowerPlantoHighPerformance.ps1 ├── Set-WindowsHelloPinComplexity.ps1 └── Win10-Network-Optimization.ps1 ├── F5 └── Enable-F5EventViewerLogs.ps1 ├── M365 ├── ComplianceSearch_DeleteEmailFrom.ps1 ├── DisableOneDriveShortcut.ps1 ├── M365_Migration │ ├── GetSouceLegacyExchangeDN.ps1 │ ├── GetSouceLegacyExchangeDN_Group.ps1 │ ├── Identity_LegacyMapping.csv │ ├── MailAddress_LegacyMapping.csv │ ├── MailAddress_LegacyMapping_Group.csv │ ├── Set_X500Address.ps1 │ ├── Set_X500Address_AD.ps1 │ └── Set_X500Address_Group.ps1 ├── MeetingRoom.ps1 └── Run-MultipleTeamsInstances.ps1 ├── OperationsMgr ├── Add_LogAnalyticsWorkspace.ps1 ├── README.md ├── Set-SCOMGroup-MaintMode.ps1 └── Set-SCOMMainMode2016.ps1 ├── Other ├── Connect-Proxy.ps1 ├── Connect_to_Secret_Server.ps1 ├── Create-LocalUser.ps1 ├── Create-Password.ps1 ├── Disable-SMB1.ps1 ├── Disk_Cleanup_C_drive.ps1 ├── DownloadAndUnzipGitRepo.ps1 ├── Drain-FailoverClusterNode.ps1 ├── Drain-NLBNode.ps1 ├── Enable-SQLPorts.ps1 ├── Event_Logs.ps1 ├── ExpiryingCertificates.ps1 ├── Export_EventLogs.ps1 ├── Get-PublicHoliday.ps1 ├── GetDateAM.ps1 ├── Increases_EphemeralPorts_2016.ps1 ├── Install-IIS.ps1 ├── Install-Printer.ps1 ├── New-EventSource.ps1 ├── PesterTests │ └── Windows10.Test.ps1 ├── README.md ├── Remove-OldModules.ps1 ├── RemoveWhiteSpaceInFilesFirstLetter.ps1 ├── RemoveWhiteSpaceInFileswith_.ps1 ├── Resolve-Port.ps1 ├── Run-PowerShellAsAdmin.ps1 ├── ServiceMonitor.ps1 ├── Start-DFS Service.ps1 ├── Start-iSCSI.ps1 ├── StartAppPool.ps1 ├── Terraform-Bootstrap.ps1 ├── Update-RoyalFolder.ps1 └── vCenter_Postqres_Backup.ps1 ├── README.md └── SCCM └── Create-UserDeviceCollections.ps1 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | /.vs/VSWorkspaceState.json 49 | /.vs/slnx.sqlite 50 | /.vs/PowerOfTheShell/v15/.suo 51 | -------------------------------------------------------------------------------- /Active Directory/ADSite.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | In a world where a server might exist on-premises today and in Azure tomorrow, locating where the server is actually located from one day to the next can be difficult. 4 | 5 | This script finds all the Windows Servers in Active Directory, then executess an Invoke-Command to connect and pull the Active Directory Site that the server exists in. 6 | It then sets the computer 7 | 8 | #> 9 | 10 | #$Servers = Import-csv 'c:\temp\servers.csv' 11 | 12 | $Servers = Get-ADComputer -Filter {OperatingSystem -like "*windows*server*"} -Properties * | Select-Object DNSHostName 13 | 14 | ForEach ($server in $servers) 15 | { 16 | Invoke-Command -ComputerName $server.Servers -ScriptBlock { 17 | $data = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name 18 | return $data 19 | } 20 | 21 | Set-ADComputer -Identity $env:computername | Set-ADComputer -Location $data 22 | } -------------------------------------------------------------------------------- /Active Directory/Copy-AD-Group-Members.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 -Modules ActiveDirectory 2 | 3 | <# 4 | 5 | Author: Luke Murray (Luke.Geek.NZ) 6 | Version: 0.1 7 | Version History: 8 | 9 | Purpose: Simple script created to copy users from one Active Directory Group into another. 10 | 11 | 12 | #> 13 | 14 | $Source_Group = 'AD_Group_SourceGroup' 15 | $Destination_Group = 'AD_Group_DestinationGroup' 16 | 17 | $Target = Get-ADGroupMember -Identity $Source_Group -Recursive 18 | foreach ($Person in $Target) { 19 | Add-ADGroupMember -Identity $Destination_Group -Members $Person.distinguishedname 20 | } -------------------------------------------------------------------------------- /Active Directory/Elevated-Rights.ps1: -------------------------------------------------------------------------------- 1 | $RequiredDays = '1' 2 | $GroupName = 'Domain Admins' 3 | $Username = 'User1' 4 | $DomainController = 'DOMAINCONTROLLER1' 5 | 6 | Invoke-Command -ComputerName $DomainController -Scriptblock { Add-ADGroupMember -Identity "$GroupName" -Members "$Username" -MemberTimeToLive (New-TimeSpan -Days $Using:RequiredDays) } -------------------------------------------------------------------------------- /Active Directory/Install_ActiveDirectory_DomainController.ps1: -------------------------------------------------------------------------------- 1 | $domain = 'luke.geek.nz' 2 | $cred = Get-Credential 3 | Set-TimeZone -Id "New Zealand Standard Time" 4 | 5 | #Installs AD Roles & Features 6 | Install-WindowsFeature AD-Domain-Services -IncludeManagementTools 7 | #Run prerequisite check 8 | Import-Module ADDSDeployment 9 | Test-ADDSDomainControllerInstallation -InstallDns -Credential $cred -DomainName $domain 10 | #If checks above look ok then run the following to install Active Directory and add to the domain 11 | Install-ADDSDomainController -InstallDns -DomainName $domain –Confirm:$False 12 | 13 | #Verify AD services are running 14 | Get-Service adws, kdc, netlogon, dns 15 | #Verify AD is replicating 16 | Get-ADReplicationPartnerMetadata -Target * -Partition * | Select-Object Server, Partition, Partner, ConsecutiveReplicationFailures, LastReplicationSuccess, LastRepicationResult 17 | 18 | #Review Logs after AD promotion for errors: 19 | Get-Eventlog "Directory Service" | select entrytype, source, eventid, message 20 | Get-Eventlog "Active Directory Web Services" | select entrytype, source, eventid, message 21 | 22 | #Install DHCP 23 | Install-WindowsFeature DHCP -IncludeManagementTools 24 | netsh dhcp add securitygroups 25 | Restart-service dhcpserver 26 | 27 | #Display the current domain functional level using PowerShell: 28 | Get-ADDomain | fl Name, DomainMode 29 | 30 | #Display the current forest functional level using PowerShell: 31 | Get-ADForest | fl Name, ForestMode 32 | 33 | #Raise Domain and Functional Level 34 | Set-ADDomainMode -identity $domain -DomainMode Windows2016Domain 35 | Set-ADForestMode -Identity $domain -ForestMode Windows2016Domain 36 | 37 | <#Downgrade Domain and Functional Level 38 | Set-ADDomainMode -identity $domain -DomainMode Windows2008R2Forest 39 | Set-ADForestMode -Identity $domain -ForestMode Windows2008R2Forest 40 | #> 41 | 42 | <#Enable AD Recycle Bin 43 | Enable-ADOptionalFeature 'Recycle Bin Feature' -Scope ForestOrConfigurationSet -Target $domain 44 | #> 45 | 46 | <#Enable PIM 47 | Enable-ADOptionalFeature 'Privileged Access Management Feature' -Scope ForestOrConfigurationSet -Target $domain 48 | #> 49 | -------------------------------------------------------------------------------- /Active Directory/README.md: -------------------------------------------------------------------------------- 1 | ## PowerofTheShell - Active Directory 2 | > This Repository is for random Active Directory PowerShell (Windows based) scripts I have created for one task or another, these will be either directly Active Directory based or based on any Active Directory Domain Service service. 3 | 4 | > I get inspiration and help from the PowerShell community so willing to give back in return, also happy if you fork any of the files - or recommend improvements. 5 | 6 | ## Usage example 7 | 8 | Unless specified otherwise, every script can usually be ran directly from Powershell or the PowerShell ISE as Administrator. 9 | These scripts are Active Directory based so need the Windows Remote Administration Tools installed or the correct Role of the server configured, installed. 10 | 11 | ## Meta 12 | 13 | Luke Murray [Twitter] – [@lukemurraynz](https://twitter.com/lukemurraynz) 14 | Luke Murray [Blog] – (http://luke.geek.nz) 15 | 16 | [https://github.com/lukemurraynz/PowerOfTheShell](https://github.com/lukemurraynz/PowerOfTheShell) 17 | 18 | [https://gist.github.com/lukemurraynz](https://gist.github.com/lukemurraynz) 19 | -------------------------------------------------------------------------------- /Active Directory/Set-ADAccountExpirationfromCSV.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 -Modules ActiveDirectory 2 | 3 | <# 4 | 5 | Author: Luke Murray 6 | Version: 1.0 7 | Version History: 8 | 9 | 1.0 - Script creation 10 | 11 | Purpose: 12 | 13 | To import CSV of users (with Firstname, Lastname values) and change the expiration date for all the accounts in the CSV. 14 | Remove '-whatif' to actually make change and change the -DateTime value to match how far ahead you want the AD account to be expired. 15 | 16 | #> 17 | 18 | $users = Import-Csv -Path C:\temp\users.csv 19 | 20 | foreach ($user in $users) { 21 | $fname = $user.Firstname 22 | $lname = $user.Lastname 23 | 24 | Get-ADUser -Filter { 25 | GivenName -eq $fname -and Surname -eq $lname 26 | } -Properties * | Set-ADAccountExpiration -DateTime '31/03/2019' -Whatif 27 | } 28 | -------------------------------------------------------------------------------- /Active Directory/Set-ADSitetoComputerLocationField.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 -Modules ActiveDirectory 2 | 3 | <# 4 | Author: Luke Murray (Luke.Geek.NZ) 5 | Version: 0.1 6 | Version History: 7 | Purpose: Script to login to a list of servers using PowerShell and grab the AD Site the server is applied to and update the servers AD Object Location field with AD site. 8 | #> 9 | 10 | #$servers = Get-ADComputer -Filter {OperatingSystem -Like "Windows *Server*"} | select-object -expandproperty name 11 | $servers = Get-Content 'C:\Temp\servers.txt' 12 | $cred = Get-Credential 13 | 14 | ForEach ($server in $servers) { 15 | 16 | $ADsite = Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock { 17 | function Get-ComputerSite { 18 | $site = nltest /dsgetsite 2>$null 19 | if ($LASTEXITCODE -eq 0) { $site[0] } 20 | } 21 | Get-ComputerSite 22 | } 23 | Set-ADComputer -Identity $server -Location $ADsite -WhatIf 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ConfigMgr/Connect-SCCM.ps1: -------------------------------------------------------------------------------- 1 | function Connect-SCCM 2 | { 3 | <# 4 | .SYNOPSIS 5 | Connects to Configuration Manager Environment via PowerShell 6 | .DESCRIPTION 7 | Function designed to Connect to the SCCM Primary Site 8 | .EXAMPLE 9 | Connect-SCCM 10 | .AUTHOR 11 | Luke Murray 12 | 13 | #> 14 | #requires -Version 2.0 15 | #Note Config Manager must be installed before the Set-Location will work. 16 | #Also the psd1 file calls a ps1xml file and the server must have it's execution policy must be allowed to run it. 17 | Import-Module -Name 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1' 18 | #Change site code to your your own environment. 19 | $sitecode = 'WNT:' 20 | Set-Location -Path $sitecode 21 | } 22 | 23 | Connect-SCCM 24 | -------------------------------------------------------------------------------- /ConfigMgr/Create-UserDeviceCollections.ps1: -------------------------------------------------------------------------------- 1 | #requires -Modules ActiveDirectory, ConfigurationManager 2 | #requires -Version 2.0 3 | 4 | <# 5 | 6 | Author: Luke Murray (Luke.Geek.NZ) 7 | Version: 0.1 8 | Version History: 9 | 10 | Purpose: To create user collections in Configuration Manager that are based on Department. 11 | 12 | This requires the Department field to be added to Active Directory User discovery in Configuration Manager. 13 | 14 | #> 15 | 16 | #Imports the Configuration Manager Module. If the Configuration Manager console is not installed in the default path, this will need to be changed. You will also need to launch PowerShell from within Configuration Manager first. 17 | Import-Module -Name "${env:ProgramFiles(x86)}\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" 18 | #Specifies the site code - this will need to be modified, depending on the site code you are using in your environment. 19 | $sitecode = 'WNT:' 20 | #Sets the location of the script to UserCollection and then creates a Departments folder. You can rename "Departments" to suit your environment. 21 | 22 | Set-Location $sitecode 23 | New-Item -Name 'UserCollection\Departments' 24 | 25 | # Helper function for creating a collection refresh schedule 26 | Function New-RandomSchedule() 27 | { 28 | "01/01/2000 $((Get-Random -Min 0 -Max 23).ToString('00')):$((Get-Random -Min 0 -Max 59).ToString('00')):00" 29 | } 30 | 31 | $Schedule = New-CMSchedule -Start (New-RandomSchedule) -RecurInterval Days -RecurCount 7 32 | 33 | #Sets the Active Directory parameters, this needs to be modified for your environment, your domain root or Domain Controller, the OU of the user accounts you want to query to obtain the departments. 34 | $ADUserParams=@{ 35 | 'Server' = 'DC1.DOMAIN.COM' 36 | 'Searchbase' = 'OU=Users,DC=DOMAINNAME,DC=COM' 37 | 'Searchscope'= 'Subtree' 38 | 'Filter' = 'Enabled -eq $True' 39 | 'Properties' = 'Department' 40 | } 41 | 42 | $departments = Get-Aduser @ADUserParams | select-object -ExpandProperty Department -Unique 43 | foreach ($department in $departments) 44 | { 45 | $UserCollection = New-CMUserCollection -Name $department -Comment "This is a user collection, based off the Department name of $department which is from the Active Directory Department field." -LimitingCollectionName 'All Users' -RefreshType Periodic -RefreshSchedule $Schedule 46 | Add-CMUserCollectionQueryMembershipRule -CollectionName $department -RuleName $department -QueryExpression ("select SMS_R_USER.ResourceID,SMS_R_USER.ResourceType,SMS_R_USER.Name,SMS_R_USER.UniqueUserName,SMS_R_USER.WindowsNTDomain from SMS_R_User where SMS_R_User.department = `"$department`" order by SMS_R_User.Name") 47 | Move-CMObject -InputObject $UserCollection -FolderPath "$sitecode\UserCollection\Departments" 48 | } -------------------------------------------------------------------------------- /ConfigMgr/Invoke-SCCM-ApplicationEval.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 1.0 2 | <# 3 | 4 | Author: Luke Murray 5 | Version: 0.1 6 | Version History: 0.1 7 | 8 | Purpose: Intended to be used to run SCCM Application policy cycles. This requires local Admin rights on the computer and has been made to be compiled into an executable that a Service Desk could use. 9 | 10 | #> 11 | 12 | $Color = 'Green' 13 | Start-Transcript -Path $env:TEMP\SCCMAppEval.log 14 | 15 | function Invoke-AppDeployEvalCycle { 16 | <# 17 | .SYNOPSIS 18 | Initiates a Application Deployment Evaluation Cycle 19 | 20 | .DESCRIPTION 21 | This will initiate a Application Deployment Evaluation Cycle. 22 | 23 | .EXAMPLE 24 | PS C:\> Invoke-AppDeployEvalCycle 25 | 26 | .NOTES 27 | Additional information about the function. 28 | #> 29 | 30 | [CmdletBinding()] 31 | param () 32 | 33 | $ComputerName = $env:COMPUTERNAME 34 | $SMSCli = [wmiclass] "\\$ComputerName\root\ccm:SMS_Client" 35 | $SMSCli.TriggerSchedule('{00000000-0000-0000-0000-000000000121}') #| Out-Null 36 | } 37 | 38 | function Invoke-DiscoveryDataCycle { 39 | <# 40 | .SYNOPSIS 41 | Initiate a Discovery Data Collection Cycle 42 | 43 | .DESCRIPTION 44 | This will initiate a Discovery Data Collection Cycle. 45 | 46 | .EXAMPLE 47 | PS C:\> Invoke-DiscoveryDataCycle 48 | 49 | .NOTES 50 | Additional information about the function. 51 | #> 52 | 53 | [CmdletBinding()] 54 | param () 55 | 56 | $ComputerName = $env:COMPUTERNAME 57 | $SMSCli = [wmiclass] "\\$ComputerName\root\ccm:SMS_Client" 58 | $SMSCli.TriggerSchedule('{00000000-0000-0000-0000-000000000003}') #| Out-Null 59 | } 60 | 61 | function Invoke-MachinePolicyCycle { 62 | <# 63 | .SYNOPSIS 64 | Initiate a Machine Policy Retrieval Cycle 65 | 66 | .DESCRIPTION 67 | This will initiate a Machine Policy Retrieval Cycle. 68 | 69 | .EXAMPLE 70 | PS C:\> Invoke-MachinePolicyCycle 71 | 72 | .NOTES 73 | Additional information about the function. 74 | #> 75 | 76 | [CmdletBinding()] 77 | param () 78 | 79 | $ComputerName = $env:COMPUTERNAME 80 | $SMSCli = [wmiclass] "\\$ComputerName\root\ccm:SMS_Client" 81 | $SMSCli.TriggerSchedule('{00000000-0000-0000-0000-000000000021}')# | Out-Null 82 | } 83 | 84 | 85 | Write-Host -ForegroundColor $Color 'Application Deployment Evaluation Cycle..' 86 | Invoke-AppDeployEvalCycle 87 | Write-Host -ForegroundColor $Color 'Discovery Data Collection Cycle..' 88 | Invoke-DiscoveryDataCycle 89 | Write-Host -ForegroundColor $Color 'Machine Policy Retrieval Cycle..' 90 | Invoke-MachinePolicyCycle 91 | Write-Host -ForegroundColor $Color Log has been outputted to: "$env:TEMP" 92 | Stop-Transcript 93 | -------------------------------------------------------------------------------- /ConfigMgr/README.md: -------------------------------------------------------------------------------- 1 | ## PowerofTheShell - Configuration Manager 2 | > This Repository is for random Configuration Manager/SCCM scripts I have created for one task or another. 3 | 4 | > I get inspiration and help from the PowerShell community so willing to give back in return, also happy if you fork any of the files - or recommend improvements. 5 | 6 | ## Usage example 7 | 8 | Unless specified otherwise, every script can usually be ran directly from Powershell or the PowerShell ISE as Administrator. 9 | These scripts are SCCM based so need to be ran from a computer that has the SCCM Console or the Module installed. 10 | 11 | ## Meta 12 | 13 | Luke Murray [Twitter] – [@lukemurraynz](https://twitter.com/lukemurraynz) 14 | Luke Murray [Blog] – (http://luke.geek.nz) 15 | 16 | [https://github.com/lukemurraynz/PowerOfTheShell](https://github.com/lukemurraynz/PowerOfTheShell) 17 | 18 | [https://gist.github.com/lukemurraynz](https://gist.github.com/lukemurraynz) 19 | -------------------------------------------------------------------------------- /DSC/Linux/ApacheUbuntuDSC.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 4.0 2 | <# 3 | Author: Luke Murray (Luke.Geek.NZ) 4 | Version: 0.1 5 | Purpose: Installing Apache/PHP 7.0 using Linux Desired State Configuration on Ubuntu Server. 6 | #> 7 | 8 | Configuration ApacheUbuntuDSC 9 | { 10 | 11 | Import-DSCResource -Module nx 12 | 13 | Node "localhost" 14 | 15 | { 16 | 17 | 18 | nxPackage apache 19 | { 20 | DependsOn = '[nxPackage]php' 21 | Name = 'apache2' 22 | Ensure = 'Present' 23 | PackageManager = 'Apt' 24 | } 25 | 26 | nxPackage php 27 | { 28 | Name = 'php7.0 libapache2-mod-php7.0 php-memcached php7.0-pspell php7.0-curl php7.0-gd php7.0-intl php7.0-mysql php7.0-xml php7.0-xmlrpc php7.0-ldap php7.0-zip php7.0-soap php7.0-mbstring' 29 | Ensure = 'Present' 30 | PackageManager = 'Apt' 31 | } 32 | 33 | nxPackage sql 34 | { 35 | Name = 'mysql-client mysql-server libpq5 php7.0-pgsql' 36 | Ensure = 'Present' 37 | PackageManager = 'Apt' 38 | } 39 | 40 | nxService apache2Service 41 | { 42 | Name = 'apache2' 43 | Controller = 'systemd' 44 | Enabled = $true 45 | State = 'Running' 46 | DependsOn = '[nxPackage]Apache' 47 | } 48 | 49 | nxPackage additionalpackages 50 | { 51 | DependsOn = '[nxPackage]Apache' 52 | Name = "graphviz aspell" 53 | Ensure = "Present" 54 | PackageManager = "Apt" 55 | } 56 | 57 | nxFile PHPInfo 58 | { 59 | DependsOn = '[nxPackage]Apache' 60 | Ensure = 'Present' 61 | Type = 'File' 62 | DestinationPath = '/var/www/html/phpinfo.php' 63 | Contents = "" 64 | } 65 | 66 | 67 | } 68 | } 69 | 70 | 71 | #ApacheUbuntuDSC -OutputPath: "C:\Temp\DSC\" -------------------------------------------------------------------------------- /DSC/Linux/DSCLinuxPush.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 -Modules Posh-SSH 2 | 3 | <# 4 | Author: Luke Murray (Luke.Geek.NZ) 5 | Version: 0.1 6 | Purpose: DSC Push configuraton created on Windows machine, and pushed to Linux DSC. 7 | #> 8 | 9 | 10 | $credential = Get-Credential 11 | $computer = 'servername.eastus.cloudapp.azure.com' 12 | $sshsession = New-SSHSession -ComputerName "$computer" -Credential $credential 13 | $mof = 'C:\Temp\DSC\localhost.mof' 14 | 15 | #Upload DSC Config file using Set-SFTPFile 16 | $SFTPSession = New-SFTPSession -ComputerName "$computer" -Credential $credential 17 | Set-SFTPFile -SFTPSession $SFTPSession -LocalFile $mof -RemotePath /tmp -Overwrite 18 | 19 | #Applies DSC Config File that was uploaded via previous command: 20 | Invoke-SSHCommand -Command {sudo /opt/microsoft/dsc/Scripts/StartDscConfiguration.py -configurationmof /tmp/localhost.mof} -SSHSession $sshsession -------------------------------------------------------------------------------- /DSC/Windows/CitrixVDA.ps1: -------------------------------------------------------------------------------- 1 | Configuration CitrixVDA 2 | { 3 | Import-DscResource -ModuleName 'PSDesiredStategConfiguration' 4 | Import-DscResource -ModuleName 'xDSCDomainjoin' 5 | param 6 | ( 7 | $dscDomainAdmin = Get-AutomationPSCredential -Name 'Default Automation Credential' 8 | $storageCredentials = Get-AutomationPSCredential -Name 'Default Automation Credential' 9 | [string] $dscDomainName = "luke.geek.nz" 10 | $sourceserver = 'SourceServer01' 11 | ) 12 | Node $env:COMPUTERNAME 13 | { 14 | #Joins the Domain 15 | xDSCDomainjoin JoinDomain 16 | { 17 | If ($env:COMPUTERNAME -contains "-C-") 18 | { 19 | 20 | Domain = $dscDomainName 21 | Credential = $dscDomainAdmin 22 | JoinOU = "OU=Citrix,OU=Servers,OU=Systems,DC=luke,DC=geek,DC=nz" 23 | } 24 | 25 | #Installs Windows Feature 26 | WindowsFeature 'Telnet-Client' 27 | { 28 | Name = 'Telnet-Client' 29 | Ensure = 'Present' 30 | } 31 | 32 | 33 | WindowsFeature 'RDS-RD-Server' 34 | { 35 | Name = 'RDS-RD-Server' 36 | Ensure = 'Present' 37 | } 38 | 39 | WindowsFeature 'WebDAV-Redirector' 40 | { 41 | Name = 'WebDAV-Redirector' 42 | Ensure = 'Present' 43 | } 44 | 45 | WindowsFeature 'RSAT-AD-Tools' 46 | { 47 | Name = 'RSAT-AD-Tools' 48 | Ensure = 'Present' 49 | } 50 | 51 | # .NET 3.5 Installs 52 | File NETSource { 53 | Type = "directory" 54 | DestinationPath = "C:\Temp\NETSource" 55 | Ensure = "Present" 56 | } 57 | 58 | File DotNet351SXS { 59 | Credential = $storageCredentials 60 | DestinationPath = "C:\NETSource\microsoft-windows-netfx3-ondemand-package.cab" 61 | SourcePath = "\\$sourceserver\CitrixVDABuild\sxs\microsoft-windows-netfx3-ondemand-package.cab" 62 | Type = "File" 63 | Ensure = "Present" 64 | DependsOn = "[File]NETSource" 65 | } 66 | 67 | WindowsFeature DotNET351 { 68 | Name = "NET-Framework-Core" 69 | Ensure = "present" 70 | Source = "C:\temp\NETSource" 71 | DependsOn = "[File]DotNet351SXS" 72 | } 73 | #Remove Windows Features 74 | WindowsFeature 'Windows-Defender' 75 | { 76 | Name = 'Windows-Defender' 77 | Ensure = 'Absent' 78 | } 79 | WindowsFeature 'Windows-Defender-GUI' 80 | { 81 | Name = 'Windows-Defender-GUI' 82 | Ensure = 'Absent' 83 | } 84 | 85 | } 86 | 87 | 88 | } -------------------------------------------------------------------------------- /DSC/Windows/InstallWindowsAdminCenter_DSC.ps1: -------------------------------------------------------------------------------- 1 | configuration WindowsAdminCenter 2 | { 3 | param 4 | ( 5 | [System.String] 6 | $WacProductId = '{7019BE31-3389-46FB-A077-B813D53C1266}', 7 | 8 | [System.String] 9 | $WacDownloadPath = 'http://download.microsoft.com/download/1/0/5/1059800B-F375-451C-B37E-758FFC7C8C8B/WindowsAdminCenter1804.25.msi', 10 | 11 | [System.Int16] 12 | $Port = 6516, 13 | 14 | [System.String] 15 | $Thumbprint 16 | ) 17 | 18 | Import-DscResource -ModuleName PSDscResources 19 | 20 | if ([System.String]::IsNullOrEmpty($Thumbprint)) 21 | { 22 | $wacInstallArguments = "/qn /l*v c:\windows\temp\windowsadmincenter.msiinstall.log SME_PORT=$Port SSL_CERTIFICATE_OPTION=generate" 23 | } 24 | else 25 | { 26 | $wacInstallArguments = "/qn /l*v c:\windows\temp\windowsadmincenter.msiinstall.log SME_PORT=$Port SME_THUMBPRINT=$Thumbprint" 27 | } 28 | 29 | Node localhost 30 | { 31 | MsiPackage InstallWindowsAdminCenter 32 | { 33 | ProductId = $WacProductId 34 | Path = $WacDownloadPath 35 | Arguments = $wacInstallArguments 36 | Ensure = 'Present' 37 | } 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /DSC/Windows/StopBITS.ps1: -------------------------------------------------------------------------------- 1 | configuration ExampleDSC 2 | { 3 | Import-DscResource -ModuleName 'PSDesiredStateConfiguration' 4 | Node localhost 5 | { 6 | Service StopBITS 7 | { 8 | Name = 'BITS' 9 | Ensure = 'Present' 10 | State = 'Stopped' 11 | } 12 | } 13 | 14 | } 15 | ExampleDSC 16 | Start-DscConfiguration ExampleDSC -Wait -Verbose -Force -------------------------------------------------------------------------------- /DSC/Windows/Windows10_Hardening.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukemurraynz/PowerOfTheShell/7e051d8691902d4832de0569144d7809367601ad/DSC/Windows/Windows10_Hardening.ps1 -------------------------------------------------------------------------------- /DSC/Windows/WindowsServer2016_Hardening.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukemurraynz/PowerOfTheShell/7e051d8691902d4832de0569144d7809367601ad/DSC/Windows/WindowsServer2016_Hardening.ps1 -------------------------------------------------------------------------------- /Desktop/Check-MicTrayExist.ps1: -------------------------------------------------------------------------------- 1 | $a = Get-Content -Path C:\temp\HPKeyLogger.txt 2 | $b = Get-Credential 3 | 4 | #requires -Version 2.0 5 | <# 6 | 7 | Author: Luke Murray (luke.geek.nz) 8 | Version: 0.1 9 | 10 | Purpose: Determines if the HP 'Keylogger' exists and if so deletes the files. 11 | 12 | https://www.bleepingcomputer.com/news/security/keylogger-found-in-audio-driver-of-hp-laptops/ 13 | 14 | With the Boolean logic can be easily modified to a Configuration Manager Configuration Baseline. 15 | 16 | #> 17 | 18 | Invoke-Command -ComputerName $a -Credential $b -ScriptBlock { 19 | 20 | if ( (Test-Path -Path $env:windir\System32\MicTray64.exe) -or (Test-Path -Path $env:windir\System32\MicTray.exe) ) 21 | { 22 | Remove-Item -Path $env:windir\System32\MicTray64.exe -ErrorAction SilentlyContinue 23 | Remove-Item -Path $env:windir\System32\MicTray.exe -ErrorAction SilentlyContinue 24 | Remove-Item -Path $env:PUBLIC\MicTray.log -ErrorAction SilentlyContinue 25 | Write-Verbose -Message True -Verbose 26 | } 27 | else 28 | { 29 | Write-Verbose -Message False -Verbose 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Desktop/Clean-AppVClientPackage.ps1: -------------------------------------------------------------------------------- 1 | #requires -Modules AppvClient 2 | #requires -Version 2.0 3 | <# 4 | Author: Luke Murray (Luke.Geek.NZ) 5 | Version: 0.1 6 | Version History: 7 | 8 | Purpose: To remove unused App-V packages older than x30 days from a clients App-V package store. Intended to be used as a Configuration Manager baseline. 9 | http://luke.geek.nz/win/rm-unused-app-v-packages-powershell-sccm. 10 | #> 11 | 12 | $log = "$env:HOMEDRIVE\temp\$env:COMPUTERNAME".log 13 | $Now = Get-Date 14 | $Days = 30 15 | $TargetFolder = "$env:ProgramData\App-V" 16 | $LastAccessTime = $Now.AddDays(-$Days) 17 | $Files = Get-ChildItem -Path $TargetFolder | Where-Object -FilterScript { 18 | $_.LastAccessTime -lt ('{0}' -f $LastAccessTime) 19 | } 20 | $null = @() 21 | if ($Files.count -gt 0) 22 | { 23 | ForEach ($null in $Files) 24 | { 25 | Start-Transcript -Append -Path $log 26 | 27 | $Result = Get-AppvClientPackage | Where-Object -FilterScript { 28 | $_.Name -notlike 'Microsoft App-V*' 29 | } 30 | 31 | foreach ($PackageId in $Result) 32 | 33 | { 34 | #The line below will remove unused packages. Please remove the '#' before the pipeline to actually remove packages. 35 | Get-AppvClientPackage -PackageId $PackageId.PackageID.Guid #| Remove-AppvClientPackage 36 | } 37 | 38 | foreach ($null in $TargetFolder) 39 | { 40 | #The line below will remove empty folders. Please remove the '#' before the pipeline to actually remove the folders. 41 | Get-ChildItem -Path $TargetFolder | Where-Object -FilterScript { 42 | $_.PSIsContainer -eq 'True' -and $_.GetFileSystemInfos().Count -eq 0 43 | } # | Remove-Item 44 | } 45 | Write-Verbose -Message 'Non-Compliant' -Verbose 46 | Stop-Transcript 47 | } 48 | } 49 | else 50 | { 51 | Start-Transcript -Append -Path $log 52 | Write-Verbose -Message 'Compliant' -Verbose 53 | Stop-Transcript 54 | } 55 | -------------------------------------------------------------------------------- /Desktop/Enable-OneDriveSyncReport.ps1: -------------------------------------------------------------------------------- 1 | #Simple script to enable OneDrive Sync Report, registry entry needs to be set on endpoint devices with the Tenant ID. 2 | # https://docs.microsoft.com/en-us/onedrive/sync-health 3 | $tenantid = '1234567890' 4 | New-Item -Path 'HKLM:\Software\Policies\Microsoft\OneDrive' -Force 5 | New-ItemProperty -LiteralPath 'HKLM:\Software\Policies\Microsoft\OneDrive' -Name 'SyncAdminReports' -Value "$tenantid" -PropertyType String -Force -------------------------------------------------------------------------------- /Desktop/Go-HomeReminder.ps1: -------------------------------------------------------------------------------- 1 | #requires -Modules BurntToast 2 | 3 | <# 4 | .SYNOPSIS 5 | Go-HomeReminder 6 | 7 | .DESCRIPTION 8 | Quick script intended to be setup as a Scheduled Task to run hourly to notify me to actually leave work! 9 | Requires the BurntToast module (https://github.com/Windos/BurntToast) 10 | 11 | .NOTES 12 | Version: 0.1 13 | Author: Luke Murray (Luke.Geek.NZ) 14 | Creation Date: 13/06/18 15 | Purpose/Change: 16 | 13/06/18 - Intiial script development 17 | 18 | #> 19 | 20 | $os = Get-WmiObject win32_operatingsystem 21 | $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime)) 22 | $round = [math]::Round($uptime.hours) 23 | 24 | If ($uptime.Hours -gt '8') { 25 | 26 | New-BurntToastNotification -Text "Go Home - your computer has been on for $round Hours" 27 | 28 | } 29 | else { 30 | 31 | New-BurntToastNotification -Text "Your computer has been on for $round hours" -SnoozeAndDismiss 32 | } -------------------------------------------------------------------------------- /Desktop/README.md: -------------------------------------------------------------------------------- 1 | ## PowerofTheShell - Desktop 2 | > This Repository is for random Windows Desktop scripts I have created for one task or another. 3 | 4 | > I get inspiration and help from the PowerShell community so willing to give back in return, also happy if you fork any of the files - or recommend improvements. 5 | 6 | ## Usage example 7 | 8 | Unless specified otherwise, every script can usually be ran directly from Powershell or the PowerShell ISE as Administrator. 9 | These scripts could be anything from App-V to WMI calls. The requirements for each script should be listed in the scripts #requires field. 10 | 11 | ## Meta 12 | 13 | Luke Murray [Twitter] – [@lukemurraynz](https://twitter.com/lukemurraynz) 14 | Luke Murray [Blog] – (http://luke.geek.nz) 15 | 16 | [https://github.com/lukemurraynz/PowerOfTheShell](https://github.com/lukemurraynz/PowerOfTheShell) 17 | 18 | [https://gist.github.com/lukemurraynz](https://gist.github.com/lukemurraynz) 19 | -------------------------------------------------------------------------------- /Desktop/Redirect-Desktop.ps1: -------------------------------------------------------------------------------- 1 | $newPath = 'E:\Desktop' 2 | $key1 = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders' 3 | $key2 = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' 4 | set-ItemProperty -Path $key1 -Name Desktop -Value $newPath 5 | set-ItemProperty -Path $key2 -Name Desktop -Value $newPath 6 | -------------------------------------------------------------------------------- /Desktop/Set-OEMInfo.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Author: Luke Murray (Luke.Geek.NZ) 3 | Version: 0.1 4 | Purpose: To add in basic OEM Info into the registry. 5 | #> 6 | 7 | Function Set-OEMInfo 8 | { 9 | $OEMKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation' 10 | Set-ItemProperty -Path $OEMKey -Name 'Model' -Value (Get-WmiObject -Class Win32_ComputerSystem).Model 11 | Set-ItemProperty -Path $OEMKey -Name 'HelpCustomized' -Value 00000000 12 | Set-ItemProperty -Path $OEMKey -Name 'SupportHours' -Value '7AM - 5PM' 13 | Set-ItemProperty -Path $OEMKey -Name 'Manufacturer' -Value 'Company Name' 14 | Set-ItemProperty -Path $OEMKey -Name 'SupportPhone' -Value '0118 999 881' 15 | Set-ItemProperty -Path $OEMKey -Name 'SupportURL' -Value 'https://www.luke.geek.nz/' 16 | } 17 | 18 | Set-OEMInfo -------------------------------------------------------------------------------- /Desktop/Set-PowerPlantoHighPerformance.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 2 | 3 | $cred = Get-Credential 4 | $computer = 'localhost' 5 | 6 | Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock { 7 | 8 | $p = Get-CimInstance -Name root\cimv2\power -Class win32_PowerPlan -Filter "ElementName = 'High Performance'" 9 | 10 | Invoke-CimMethod -InputObject $p -MethodName Activate 11 | } 12 | -------------------------------------------------------------------------------- /Desktop/Set-WindowsHelloPinComplexity.ps1: -------------------------------------------------------------------------------- 1 | #Simple script to change Windows Hello PINComplexity to: Minimum of 4 chars, not 6. 2 | New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity' -Force 3 | New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity' -Name 'MinimumPINLength' -Value 4 -PropertyType DWord -Force 4 | New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity' -Name 'MaximumPINLength' -Value 10 -PropertyType DWord -Force 5 | #PC needs to be restarted to pickup the PIN requirements 6 | #Restart-Computer -Force -------------------------------------------------------------------------------- /Desktop/Win10-Network-Optimization.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Sets some TCP and Windows 10 network/TCP optimization settings. 4 | .DESCRIPTION 5 | Sets some TCP and Windows 10 network/TCP optimization settings. The intention is for the script to make some quick registry changes that could help with network performance. 6 | Please note, I take no responsibility for the impact of this script and make sure you have a registry backup before running it. 7 | .AUTHOR: Luke Murray (Luke.Geek.NZ) 8 | .VERSION: 0.1 9 | #> 10 | 11 | 12 | #Turns off Windows Update Peering (Allow Downloads from other PCs) 13 | Set-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Settings -Name DownloadMode -Value '0' 14 | 15 | #Uninstall OneNote AppX Package 16 | Get-AppxPackage *OneNote* | Remove-AppxPackage 17 | 18 | #Disable Window Auto-Tuning 19 | netsh int tcp set global autotuninglevel=disabled  20 | 21 | #Disables Large Send Offload V2 (IPv4 + IPv6) 22 | 23 | $adapters = Get-NetAdapter 24 | ForEach ($adapter in $adapters) 25 | { 26 | Disable-NetAdapterChecksumOffload -Name $adapter.Name 27 | 28 | } 29 | 30 | #Limits Reversible bandwith - Stops Windows from reserving 20% of bandwidth for OS tasks 31 | 32 | Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\Psched -Name NonBestEffortLimit -Value '0' 33 | -------------------------------------------------------------------------------- /F5/Enable-F5EventViewerLogs.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 2 | $VerbosePreference = 'continue' 3 | Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Confirm:$false -Force 4 | 5 | Write-Host -NoNewline -Object 'Press Any key when you are ready - Make sure you run this as Administrator...' 6 | $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') 7 | 8 | #Creates folder for PowerShell Script Logs + Event Viewer Logs 9 | $Computer = $env:COMPUTERNAME 10 | $date = Get-Date -Format dd-MM-yyyy 11 | $path = "C:\temp\$Computer\" 12 | 13 | New-Item -Force -ItemType directory -Path $env:HOMEDRIVE\temp 14 | 15 | If(!(Test-Path $path)) 16 | { 17 | New-Item -ItemType Directory -Force -Path $path 18 | } 19 | 20 | #Enables Windows Networking Event Viewer Logs 21 | Write-Host -Object 'Starting PowerShell Logging...' -ForegroundColor Green 22 | Start-Transcript -Path "$path\PSTransScript _ $date _.log" 23 | Write-Host -Object 'Enabling Windows Networking VPN Operational Logs' -ForegroundColor Green 24 | $wineventlog = Get-WinEvent -ListLog 'Windows Networking Vpn Plugin Platform/Operational' 25 | $wineventlog.IsEnabled = $true 26 | $wineventlog.SaveChanges() 27 | 28 | Write-Host -Object 'Enabling Windows Networking VPN Operational Verbose Logs' -ForegroundColor Green 29 | 30 | $wineventlog = Get-WinEvent -ListLog 'Windows Networking Vpn Plugin Platform/OperationalVerbose' 31 | $wineventlog.IsEnabled = $true 32 | $wineventlog.SaveChanges() 33 | 34 | Write-Host -Object "The Logs have now been enabled, you can leave this application open to export the logs when you have an issue or close it if you don't need to export them!" -ForegroundColor Green 35 | 36 | Write-Host -NoNewline -Object 'Press any key to export the logs for analysis...' 37 | $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') 38 | 39 | Write-Host -Object 'Waiting for 10 more seconds to collect more logs...' -ForegroundColor Green 40 | Start-Sleep -Seconds 10 41 | Write-Host -Object 'Exporting Event Logs for the VPN...' -ForegroundColor Green 42 | 43 | Copy-Item "$ENV:SystemRoot\System32\Winevt\Logs\Windows Networking Vpn Plugin Platform%4Operational.evtx" $path -Force 44 | Copy-Item "$ENV:SystemRoot\System32\Winevt\Logs\Windows Networking Vpn Plugin Platform%4OperationalVerbose.evtx" $path -Force 45 | Copy-Item "$ENV:SystemRoot\System32\Winevt\Logs\Microsoft-Windows-VPN-Client%4Operational.evtx" $path -Force 46 | Copy-Item "$ENV:SystemRoot\System32\Winevt\Logs\Microsoft-Windows-DNS-Client%4Operational.evtx" $path -Force 47 | 48 | 49 | Write-Host -Object 'Exporting IP Configuration...' -ForegroundColor Green 50 | 51 | & "$env:windir\system32\ipconfig.exe" /all > $path\"$Computer"_ipconfig1.txt 52 | 53 | Write-Host -Object 'Stopping PowerShell Logging...' -ForegroundColor Green 54 | 55 | Stop-Transcript 56 | Write-Host -Object 'Zipping up log files...' -ForegroundColor Green 57 | 58 | Remove-Item -Path "c:\temp\VPNLogs+$Computer.zip" -Force | Out-Null 59 | 60 | $LogSource = "$env:HOMEDRIVE\temp\" 61 | $ZipFileName = "VPNLogs+$Computer.zip" 62 | 63 | Add-Type -AssemblyName 'System.IO.Compression.FileSystem' 64 | [System.IO.Compression.ZipFile]::CreateFromDirectory($path, $LogSource+$ZipFileName) 65 | 66 | Write-Host -Object 'Attempting to email log files to ITServiceDesk/Cloud & Enterprise mailboxes...' -ForegroundColor Green 67 | $IP = Get-NetIPConfiguration | Out-String 68 | 69 | $Email = New-Object -ComObject 'CDO.Message' 70 | $Email.Configuration.Fields.Item('http://schemas.microsoft.com/cdo/configuration/sendusing') = 2 71 | $Email.Configuration.Fields.Item('http://schemas.microsoft.com/cdo/configuration/smtpserver') = 'smtprelay.domain.co.nz' 72 | $Email.Configuration.Fields.Item('http://schemas.microsoft.com/cdo/configuration/smtpserverport') = 25 73 | $Email.Configuration.Fields.Update() 74 | 75 | $Email.From = "$Computer@domain.co.nz" 76 | $Email.To = 'supportdesk@@domain.co.nz' 77 | $Email.Subject = "$Computer - VPN Logs $date" 78 | $Email.TextBody = "$IP" 79 | #$Email.AddAttachment($file) 80 | $Email.Send() 81 | 82 | Write-Host -Object 'Client IP should be sent, Logs are stored in c:\temp!' -ForegroundColor Green 83 | -------------------------------------------------------------------------------- /M365/ComplianceSearch_DeleteEmailFrom.ps1: -------------------------------------------------------------------------------- 1 |  #Log into M365 2 | Connect-IPPSSession -UserPrincipalName' it@name.co.nz' 3 | #Start Compliance Search 4 | New-ComplianceSearch -Name Phish -ExchangeLocation All -ContentMatchQuery 'from:"badaddress@badcompany.com"' 5 | Start-ComplianceSearch -Identity Phish 6 | #Get Compliance Search 7 | Get-ComplianceSearch -Identity Phish | Format-list * 8 | #Delete Emails retrieved from Compliance Search 9 | New-ComplianceSearchAction -SearchName Phish -Purge -PurgeType HardDelete 10 | Get-ComplianceSearchAction -------------------------------------------------------------------------------- /M365/DisableOneDriveShortcut.ps1: -------------------------------------------------------------------------------- 1 | #Disable the "Add shortcut to OneDrive" 2 | 3 | $Sharepoint = https://COMPANY-admin.sharepoint.com 4 | Connect-SPOService $Sharepoint 5 | Set-SPOTenant -DisableAddShortCutsToOneDrive $True 6 | 7 | To enable it again you can run: 8 | 9 | Set-SPOTenant -DisableAddShortCutsToOneDrive $False 10 | -------------------------------------------------------------------------------- /M365/M365_Migration/GetSouceLegacyExchangeDN.ps1: -------------------------------------------------------------------------------- 1 | $invocation = (Get-Variable MyInvocation).Value 2 | $currentPath = (Get-Item $invocation.MyCommand.Path).Directory.FullName 3 | $timestamp = Get-Date -UFormat %Y%m%d%H%M%S 4 | $reportPath="$currentPath\SourceLegacyExchangeDN_$timestamp.csv"; 5 | try 6 | { 7 | Get-mailbox|select-object primarysmtpaddress,legacyexchangedn|Export-csv $reportPath -NoTypeInformation -ErrorAction Stop 8 | Write-Host "Finished. File Path: $($reportPath)" 9 | } 10 | catch [System.Exception] 11 | { 12 | Write-Warning "Failed to get SourceLegacyExchangeDN. Reason:$($_.Exception.Message)" 13 | } 14 | -------------------------------------------------------------------------------- /M365/M365_Migration/GetSouceLegacyExchangeDN_Group.ps1: -------------------------------------------------------------------------------- 1 | $invocation = (Get-Variable MyInvocation).Value 2 | $currentPath = (Get-Item $invocation.MyCommand.Path).Directory.FullName 3 | $timestamp = Get-Date -UFormat %Y%m%d%H%M%S 4 | $reportPath="$currentPath\SourceLegacyExchangeDN_Group_$timestamp.csv"; 5 | try 6 | { 7 | Get-UnifiedGroup|select-object primarysmtpaddress,legacyexchangedn|Export-csv $reportPath -NoTypeInformation -ErrorAction Stop 8 | Write-Host "Finished. File Path: $($reportPath)" 9 | } 10 | catch [System.Exception] 11 | { 12 | Write-Warning "Failed to get SourceLegacyExchangeDN. Reason:$($_.Exception.Message)" 13 | } 14 | -------------------------------------------------------------------------------- /M365/M365_Migration/Identity_LegacyMapping.csv: -------------------------------------------------------------------------------- 1 | "Identity","LegacyExchangeDN" 2 | "demouser1","/o=exchangedemo/ou=exchange administrative group (testdemo)/cn=recipients/cn=c5b8a1b8d3074d6dba1b07b69ebab827-demouser1" 3 | "demouser2","/o=exchangedemo/ou=exchange administrative group (testdemo)/cn=recipients/cn=c5b8a1b8d3074d6dba1b07b69ebab827-demouser2" 4 | -------------------------------------------------------------------------------- /M365/M365_Migration/MailAddress_LegacyMapping.csv: -------------------------------------------------------------------------------- 1 | MailAddress,LegacyExchangeDN 2 | demouser1@contoso.onmicrosoft.com,/o=exchangedemo/ou=exchange administrative group (testdemo)/cn=recipients/cn=c5b8a1b8d3074d6dba1b07b69ebab827-demouser1 3 | demouser2@contoso.onmicrosoft.com,/o=exchangedemo/ou=exchange administrative group (testdemo)/cn=recipients/cn=c5b8a1b8d3074d6dba1b07b69ebab827-demouser2 4 | -------------------------------------------------------------------------------- /M365/M365_Migration/MailAddress_LegacyMapping_Group.csv: -------------------------------------------------------------------------------- 1 | MailAddress,LegacyExchangeDN 2 | -------------------------------------------------------------------------------- /M365/M365_Migration/Set_X500Address.ps1: -------------------------------------------------------------------------------- 1 | $invocation = (Get-Variable MyInvocation).Value 2 | $currentPath = (Get-Item $invocation.MyCommand.Path).Directory.FullName 3 | $timestamp = Get-Date -UFormat %Y%m%d%H%M%S 4 | $csvContent = Import-Csv "$currentPath\MailAddress_LegacyMapping.csv" 5 | $reportPath="$currentPath\Set_X500Address_Report_$timestamp.csv"; 6 | $ret = @() 7 | foreach($info in $csvContent){ 8 | try 9 | { 10 | Write-Host "Start to Set Mailbox: $($info.MailAddress)" 11 | Set-Mailbox -Identity $info.MailAddress -EmailAddresses @{Add ='X500:'+$info.LegacyExchangeDN} -ErrorAction Stop 12 | Write-Host "Successful to Set Mailbox: $($info.MailAddress)" 13 | $mobj = New-Object -TypeName PSCustomObject 14 | $mobj | Add-Member -MemberType NoteProperty -Name "MailAddress" -Value $info.MailAddress 15 | $mobj | Add-Member -MemberType NoteProperty -Name "LegacyExchangeDN" -Value $info.LegacyExchangeDN 16 | $mobj | Add-Member -MemberType NoteProperty -Name "Status" -Value "Successfull" 17 | $mobj | Add-Member -MemberType NoteProperty -Name "Comment" -Value "" 18 | $ret += $mobj 19 | 20 | } 21 | catch [System.Exception] 22 | { 23 | Write-Warning "Failed to set mailbox: $($info.MailAddress). Reason:$($_.Exception.Message)" 24 | $mobj = New-Object -TypeName PSCustomObject 25 | $mobj | Add-Member -MemberType NoteProperty -Name "MailAddress" -Value $info.MailAddress 26 | $mobj | Add-Member -MemberType NoteProperty -Name "LegacyExchangeDN" -Value $info.LegacyExchangeDN 27 | $mobj | Add-Member -MemberType NoteProperty -Name "Status" -Value "Failed" 28 | $mobj | Add-Member -MemberType NoteProperty -Name "Comment" -Value $_.Exception.Message 29 | $ret += $mobj 30 | 31 | } 32 | } 33 | Write-Host "Finished. Please check the report for details. Path: $($reportPath)" 34 | $ret | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8 35 | -------------------------------------------------------------------------------- /M365/M365_Migration/Set_X500Address_AD.ps1: -------------------------------------------------------------------------------- 1 | $invocation = (Get-Variable MyInvocation).Value 2 | $currentPath = (Get-Item $invocation.MyCommand.Path).Directory.FullName 3 | $timestamp = Get-Date -UFormat %Y%m%d%H%M%S 4 | $csvContent = Import-Csv "$currentPath\Identity_LegacyMapping.csv" 5 | $reportPath="$currentPath\Set_X500Address_AD_Report_$timestamp.csv"; 6 | $ret = @() 7 | foreach($info in $csvContent){ 8 | try 9 | { 10 | Write-Host "Start to Set User: $($info.Identity)" 11 | Set-ADUser -Identity $info.Identity -add @{proxyAddresses="X500:$($info.LegacyExchangeDN)"} -ErrorAction Stop 12 | Write-Host "Successful to Set User: $($info.Identity)" 13 | $mobj = New-Object -TypeName PSCustomObject 14 | $mobj | Add-Member -MemberType NoteProperty -Name "Identity" -Value $info.Identity 15 | $mobj | Add-Member -MemberType NoteProperty -Name "LegacyExchangeDN" -Value $info.LegacyExchangeDN 16 | $mobj | Add-Member -MemberType NoteProperty -Name "Status" -Value "Successfull" 17 | $mobj | Add-Member -MemberType NoteProperty -Name "Comment" -Value "" 18 | $ret += $mobj 19 | } 20 | catch [System.Exception] 21 | { 22 | Write-Warning "Failed to Get User: $($info.Identity). Reason:$($_.Exception.Message)" 23 | $mobj = New-Object -TypeName PSCustomObject 24 | $mobj | Add-Member -MemberType NoteProperty -Name "Identity" -Value $info.Identity 25 | $mobj | Add-Member -MemberType NoteProperty -Name "LegacyExchangeDN" -Value $info.LegacyExchangeDN 26 | $mobj | Add-Member -MemberType NoteProperty -Name "Status" -Value "Failed" 27 | $mobj | Add-Member -MemberType NoteProperty -Name "Comment" -Value $_.Exception.Message 28 | $ret += $mobj 29 | } 30 | } 31 | Write-Host "Finished. Please check the report for details. Path: $($reportPath)" 32 | $ret | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8 -------------------------------------------------------------------------------- /M365/M365_Migration/Set_X500Address_Group.ps1: -------------------------------------------------------------------------------- 1 | $invocation = (Get-Variable MyInvocation).Value 2 | $currentPath = (Get-Item $invocation.MyCommand.Path).Directory.FullName 3 | $timestamp = Get-Date -UFormat %Y%m%d%H%M%S 4 | $csvContent = Import-Csv "$currentPath\MailAddress_LegacyMapping_Group.csv" 5 | $reportPath="$currentPath\Set_X500Address_Group_Report_$timestamp.csv"; 6 | $ret = @() 7 | foreach($info in $csvContent){ 8 | try 9 | { 10 | Write-Host "Start to Set Mailbox: $($info.MailAddress)" 11 | Set-UnifiedGroup -Identity $info.MailAddress -EmailAddresses @{Add ='X500:'+$info.LegacyExchangeDN} -ErrorAction Stop 12 | Write-Host "Successful to Set Mailbox: $($info.MailAddress)" 13 | $mobj = New-Object -TypeName PSCustomObject 14 | $mobj | Add-Member -MemberType NoteProperty -Name "MailAddress" -Value $info.MailAddress 15 | $mobj | Add-Member -MemberType NoteProperty -Name "LegacyExchangeDN" -Value $info.LegacyExchangeDN 16 | $mobj | Add-Member -MemberType NoteProperty -Name "Status" -Value "Successfull" 17 | $mobj | Add-Member -MemberType NoteProperty -Name "Comment" -Value "" 18 | $ret += $mobj 19 | 20 | } 21 | catch [System.Exception] 22 | { 23 | Write-Warning "Failed to set mailbox: $($info.MailAddress). Reason:$($_.Exception.Message)" 24 | $mobj = New-Object -TypeName PSCustomObject 25 | $mobj | Add-Member -MemberType NoteProperty -Name "MailAddress" -Value $info.MailAddress 26 | $mobj | Add-Member -MemberType NoteProperty -Name "LegacyExchangeDN" -Value $info.LegacyExchangeDN 27 | $mobj | Add-Member -MemberType NoteProperty -Name "Status" -Value "Failed" 28 | $mobj | Add-Member -MemberType NoteProperty -Name "Comment" -Value $_.Exception.Message 29 | $ret += $mobj 30 | 31 | } 32 | } 33 | Write-Host "Finished. Please check the report for details. Path: $($reportPath)" 34 | $ret | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8 35 | -------------------------------------------------------------------------------- /M365/MeetingRoom.ps1: -------------------------------------------------------------------------------- 1 | #Sets Password to account: 2 | $RoomMailboxIdentity = 'MeetingRoom' 3 | $RoomMailPassword = 'password' 4 | Set-Mailbox -Identity $RoomMailboxIdentity -EnableRoomMailboxAccount $true -RoomMailboxPassword (ConvertTo-SecureString -String "$RoomMailPassword" -AsPlainText -Force) 5 | 6 | #Set Meeting Room reqiremtns 7 | Set-CalendarProcessing -Identity MeetingRoom@contoso.com -AutomateProcessing AutoAccept -AddOrganizerToSubject $false -DeleteComments $false -DeleteSubject $false 8 | <# 9 | AutomateProcessing: AutoAccept (Meeting organizers receive the room reservation decision directly without human intervention: free = accept; busy = decline.) 10 | AddOrganizerToSubject: $false (The meeting organizer is not added to the subject of the meeting request.) 11 | DeleteComments: $false (Keep any text in the message body of incoming meeting requests.) 12 | DeleteSubject: $false (Keep the subject of incoming meeting requests.) 13 | RemovePrivateProperty: $false (Ensures the private flag that was sent by the meeting organizer in the original meeting request remains as specified.) 14 | AddAdditionalResponse: $true (The text specified by the AdditionalResponse parameter is added to meeting requests.) 15 | AdditionalResponse: "This is a Teams Meeting room!" (The additional text to add to the meeting request.) 16 | #> 17 | 18 | #Set password to Never expire 19 | $cred 20 | Connect-MsolService -Credential $cred 21 | Set-MsolUser -UserPrincipalName MeetingRoom@contoso.com -PasswordNeverExpires $true 22 | 23 | #Allow forwarding, meeting invites from external domains 24 | #To check status: 25 | Get-Mailbox MeetingRoom@contoso.com | Get-CalendarProcessing | Select *external* 26 | #To allow external: 27 | Get-Mailbox MeetingRoom@contoso.com | Set-CalendarProcessing -ProcessExternalMeetingMessages $true 28 | 29 | #MicrosoftTeamsPSTN 30 | 31 | Import-Module SkypeOnlineConnector 32 | $cssess=New-CsOnlineSession -Credential $cred 33 | Import-PSSession $cssess -AllowClobber 34 | 35 | #Find the registrar pool - take note of the result, you will need this shortly. 36 | Get-CsOnlineUser -Identity $rm | Select -Expand RegistrarPool 37 | 38 | #Enable the room account for teams, using the registrar pool name from above 39 | Enable-CsMeetingRoom -Identity MeetingRoom@contoso.com -RegistrarPool "pool name from the above line of code" -SipAddressType EmailAddress -------------------------------------------------------------------------------- /M365/Run-MultipleTeamsInstances.ps1: -------------------------------------------------------------------------------- 1 | # Uses the file name as the profile name 2 | $MSTEAMS_PROFILE = 'CustomProfile' 3 | 4 | Write-Host "- Using profile '$MSTEAMS_PROFILE'" 5 | 6 | # Set the custom profile path 7 | $USERPROFILE = Join-Path $env:LOCALAPPDATA "Microsoft\Teams\CustomProfiles\$MSTEAMS_PROFILE" 8 | 9 | # Set the old user profile 10 | $OLD_USERPROFILE = $env:USERPROFILE 11 | 12 | # Launch MS Teams with the custom profile 13 | Write-Host "- Launching MS Teams with profile '$MSTEAMS_PROFILE'" 14 | Set-Location "$OLD_USERPROFILE\AppData\Local\Microsoft\Teams" 15 | 16 | $teamsProcessStartInfo = New - Object System.Diagnostics.ProcessStartInfo 17 | $teamsProcessStartInfo.FileName = "$OLD_USERPROFILE\AppData\Local\Microsoft\Teams\Update.exe" 18 | $teamsProcessStartInfo.Arguments = "--processStart ""Teams.exe""" 19 | $teamsProcessStartInfo.WorkingDirectory = "$OLD_USERPROFILE\AppData\Local\Microsoft\Teams" 20 | $teamsProcessStartInfo.EnvironmentVariables["USERPROFILE"] = $USERPROFILE 21 | $teamsProcessStartInfo.UseShellExecute = $false 22 | 23 | [System.Diagnostics.Process]::Start($teamsProcessStartInfo) | Out-Null 24 | 25 | # Set the user profile back to the old user profile 26 | $env:USERPROFILE = $OLD_USERPROFILE 27 | -------------------------------------------------------------------------------- /OperationsMgr/Add_LogAnalyticsWorkspace.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Luke Murray (Luke.Geek.NZ) 4 | Version: 0.1 5 | Version History: 6 | 7 | Purpose: Add an MMA agent to a Log Analytics workspace using a proxy with no user authentication. 8 | Notes: 9 | Find more options about the MMA Agent Object: 10 | #$healthServiceSettings = New-Object -ComObject 'AgentConfigManager.MgmtSvcCfg' 11 | #$proxyMethod = $healthServiceSettings | Get-Member -Name 'SetProxyInfo' 12 | 13 | If script is being published by Configuration as a package, create a Command Line installer: 14 | "%Windir%\sysnative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass -Command .\Add_LogAnalyticsWorkspace.ps1 15 | 16 | If the proxy requires authentication, then the following null entries need to be replaced with user,password: $mma.SetProxyInfo("$proxy","$null","$null"). If you aren't using a proxy then you can remove the entire mma.SetProxyInfo line. 17 | 18 | Location: https://github.com/lukemurraynz/PowerOfTheShell/blob/master/OperationsMgr/Add_LogAnalyticsWorkspace.ps1 19 | #> 20 | 21 | $workspaceId = "INSERTLOGANALYTICSWORKSPACEIDHERE" 22 | $workspaceKey = "INSERTLOGANALYTICSWORKSPACEKEY" 23 | $proxy = 'ProxyIP:PORT' 24 | $mma = New-Object -ComObject 'AgentConfigManager.MgmtSvcCfg' 25 | $mma.AddCloudWorkspace($workspaceId, $workspaceKey) 26 | $mma.SetProxyInfo("$proxy","$null","$null") 27 | $mma.ReloadConfiguration() -------------------------------------------------------------------------------- /OperationsMgr/README.md: -------------------------------------------------------------------------------- 1 | ## PowerofTheShell - Operations Manager/SCOM 2 | > This Repository is for random SCOM scripts I have created for one task or another. 3 | 4 | > I get inspiration and help from the PowerShell community so willing to give back in return, also happy if you fork any of the files - or recommend improvements. 5 | 6 | ## Usage example 7 | 8 | Unless specified otherwise, every script can usually be ran directly from Powershell or the PowerShell ISE as Administrator. 9 | These scripts usually would be ran on the SCOM server or remotely using PSSession. 10 | 11 | ## Meta 12 | 13 | Luke Murray [Twitter] – [@lukemurraynz](https://twitter.com/lukemurraynz) 14 | Luke Murray [Blog] – (http://luke.geek.nz) 15 | 16 | [https://github.com/lukemurraynz/PowerOfTheShell](https://github.com/lukemurraynz/PowerOfTheShell) 17 | 18 | [https://gist.github.com/lukemurraynz](https://gist.github.com/lukemurraynz) 19 | -------------------------------------------------------------------------------- /OperationsMgr/Set-SCOMGroup-MaintMode.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Luke Murray (Luke.Geek.NZ) 4 | Version: 0.1 5 | Version History: 6 | 7 | Purpose: To place an Operations Manager server group into maintenance mode for 120 minutes. 8 | The $SCOMSERVER variable needs to change to point to your SCOM server and PowerShell Remoting (Enable-PSRemoting) needs to be enabled. 9 | The SCOMGroup Display name needs to also be changed to the group you want to place into maintenance mode. 10 | This needs to be run under a SCOM Administrator account. 11 | 12 | #> 13 | 14 | $SCOMServer = 'SCOMSERVER.DOMAIN.LOCAL' 15 | enter-pssession -computername $SCOMServer -Credential (Get-Credential) 16 | invoke-command -computername $SCOMServer -scriptblock { 17 | 18 | Import-Module -Name OperationsManager 19 | $Instance = Get-SCOMGroup -displayname 'Patching Group 1' | Get-SCOMClassInstance 20 | $Time = ((Get-Date).AddMinutes(120)) 21 | Start-SCOMMaintenanceMode -Instance $Instance -EndTime $Time -Reason 'PlannedOther' -Comment 'Server Patching' 22 | 23 | } 24 | Exit-Pssession -------------------------------------------------------------------------------- /OperationsMgr/Set-SCOMMainMode2016.ps1: -------------------------------------------------------------------------------- 1 | #Runs from SCOM agent on server (requires SCOM 2016) 2 | 3 | $duration = '10' 4 | $reason = 'ApplicationInstallation' 5 | $comment = 'Comment' 6 | 7 | Import-module “C:\Program Files\Microsoft Monitoring Agent\Agent\MaintenanceMode.dll” 8 | Start-SCOMAgentMaintenanceMode -Duration $duration -Reason $reason -Comment “Test” 9 | 10 | <# 11 | 12 | The following reasons are accepted by the cmdlet: 13 | 14 | Requires SCOM 2016 15 | 16 | PlannedOther 17 | UnplannedOther 18 | PlannedHardwareMaintenance 19 | UnplannedHardwareMaintenance 20 | PlannedHardwareInstallation 21 | UnplannedHardwareInstallation 22 | PlannedOperatingSystemReconfiguration 23 | UnplannedOperatingSystemReconfiguration 24 | PlannedApplicationMaintenance 25 | UnplannedApplicationMaintenance 26 | ApplicationInstallation 27 | ApplicationUnresponsive 28 | ApplicationUnstable 29 | SecurityIssue 30 | LossOfNetworkConnectivity 31 | 32 | #> 33 | 34 | 35 | #Function below checks what the maint mode settings are from the registry key: 36 | function Get-SCOMAgentMaintenanceMode { 37 | $mm=(Get-ItemProperty “hklm:\software\microsoft\microsoft operations manager\3.0\maintenancemode”).Record 38 | $split=$mm.split(“|”) 39 | write-host “Duration:”$split[0]” 40 | Reason:”$split[1]” 41 | User:”$split[2].split(“:”)[0]” 42 | Comment:”$split[2].split(“:”)[1]” 43 | StartTime:”$split[3] 44 | } 45 | Get-SCOMAgentMaintenanceMode 46 | -------------------------------------------------------------------------------- /Other/Connect-Proxy.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 3.0 2 | function Connect-Proxy 3 | { 4 | <# 5 | .SYNOPSIS 6 | Basic Function to prompt for Proxy credentials to allow PowerShell to use a Proxy. 7 | .AUTHOR: Luke Murray (Luke.Geek.NZ) 8 | .VERSION: 0.1 9 | .EXAMPLE 10 | Connect-Proxy 11 | 12 | #> 13 | $webclient=New-Object System.Net.WebClient 14 | $creds=Get-Credential 15 | $webclient.Proxy.Credentials=$creds 16 | } 17 | 18 | Connect-Proxy 19 | 20 | #Does an Update-Help to test Proxy works: 21 | Update-Help -Force -------------------------------------------------------------------------------- /Other/Connect_to_Secret_Server.ps1: -------------------------------------------------------------------------------- 1 | #Uses the Secret Server Module, to connect to a locally installed Secret Server instance and pulls the credential to be used in scripts. 2 | # https://www.powershellgallery.com/packages/SecretServer/1.0 3 | 4 | Import-Module SecretServer 5 | Set-SecretServerConfig -Uri https://secretserver.domain.co.nz/secretserver/winauthwebservices/SSWinAuthWebService.asmx 6 | New-SSConnection #Uses Uri we just set by default 7 | $secretname = 'MySecret' 8 | 9 | $Credential = (Get-Secret -SearchTerm $secretname -IncludeRestricted -as Credential ).Credential 10 | $Credential 11 | -------------------------------------------------------------------------------- /Other/Create-LocalUser.ps1: -------------------------------------------------------------------------------- 1 |  2 | #Creates random password and creates Local User Account 3 | 4 | $minLength = 5 ## characters 5 | $maxLength = 64 ## characters 6 | $length = Get-Random -Minimum $minLength -Maximum $maxLength 7 | $nonAlphaChars = 5 8 | Add-type -AssemblyName System.Web 9 | $password = [System.Web.Security.Membership]::GeneratePassword($length, $nonAlphaChars) 10 | $secPw = ConvertTo-SecureString -String $password -AsPlainText -Force 11 | 12 | 13 | $Username = 'LastNameFirstName' 14 | New-LocalUser "$Username" -Password $secPw -FullName "FirstName Lastname" -Description "Vendor - Local Administrator Account." 15 | Add-LocalGroupMember -Group 'Administrators' -Member "$Username" 16 | 17 | #Publishes the password to pwpush and supplies URL. 18 | function New-PasswordLink { 19 | [Alias("pwpush")] 20 | [CmdletBinding(DefaultParameterSetName = 'ProvidedPassword')] 21 | param ( 22 | [Parameter(Mandatory = $true, 23 | ParameterSetName = 'ProvidedPassword')] 24 | $Password = "$password", 25 | 26 | [Int] 27 | [ValidateRange(5, 64)] 28 | [Parameter(ParameterSetName = 'GeneratedPassword')] 29 | $PasswordLength = 12, 30 | 31 | [Int] 32 | [ValidateScript( { if ($_ -ge 0 -and $_ -le $PasswordLength) { $true }else { $false } })] 33 | [Parameter(ParameterSetName = 'GeneratedPassword')] 34 | $MinimumNumberOfNonAlphaCharacters = 0, 35 | 36 | [Int] 37 | [ValidateRange(1, 90)] 38 | $ExpireInDays = 7, 39 | 40 | [Int] 41 | [ValidateRange(1, 100)] 42 | $ExpireInViews = 5, 43 | 44 | [Switch] 45 | $Deletable = $true 46 | ) 47 | 48 | # Generate password if not specified 49 | if ($Password -eq '') { 50 | Add-Type -AssemblyName System.Web 51 | $Password = [System.Web.Security.Membership]::GeneratePassword($PasswordLength, $MinimumNumberOfNonAlphaCharacters) 52 | } 53 | 54 | # Prepare and fill body 55 | $body = @{ 56 | 'payload' = $Password 57 | 'expire_after_days' = $ExpireInDays 58 | 'expire_after_views' = $ExpireInViews 59 | } 60 | 61 | # Dunno why, but any value passed to this parameter is considered on, so to turn it "off", you don't add the parameter 62 | if ($Deletable) { 63 | $body | Add-Member 'deletable_by_viewer' 'on' 64 | } 65 | 66 | # Prepare result object 67 | $result = @{ 68 | URI = 'https://pwpush.com/p/' 69 | Password = $Password 70 | } 71 | 72 | # Post and retrieve link 73 | $result.URI += (Invoke-RestMethod -Uri "https://pwpush.com/p.json" -Body ($body | ConvertTo-Json) -Method Post -ContentType "application/json").url_token 74 | 75 | # Return result 76 | $result 77 | } 78 | New-PasswordLink -Password $password -------------------------------------------------------------------------------- /Other/Create-Password.ps1: -------------------------------------------------------------------------------- 1 | # Import System.Web assembly 2 | Add-Type -AssemblyName System.Web 3 | # Generate random password 4 | $password = [System.Web.Security.Membership]::GeneratePassword(128,2) 5 | -------------------------------------------------------------------------------- /Other/Disable-SMB1.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 3.0 -Modules Dism 2 | 3 | <# 4 | .SYNOPSIS 5 | Disables SMB1 6 | 7 | .DESCRIPTION 8 | This script disables SMB1. If Windows 10 or greater it will use the PowerShell cmdlet to disable SMB1 with no restart, if the OS is 9 | less than Windows 10 - such as Windows 7 it will set the services to be disabled manually. Needs to be run as Administrator. 10 | 11 | .NOTES 12 | Version: 1.0 13 | Author: Luke Murray 14 | Creation Date: 14/05/17 15 | Purpose/Change: 16 | 14/05/17 - Initial script creation 17 | 09/06/18 - Script formatting changed and elevation function put in. 18 | 19 | 20 | .EXAMPLE 21 | ./Disable-SMB1.ps1 22 | 23 | #> 24 | 25 | 26 | #---------------------------------------------------------[Initialisations]-------------------------------------------------------- 27 | 28 | #Set Error Action to Stop 29 | $ErrorActionPreference = 'Stop' 30 | 31 | #If script not ran as Administrator, request elevation of privilages and run script. 32 | 33 | if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) 34 | { 35 | if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) 36 | { 37 | $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments 38 | 39 | Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine 40 | 41 | Exit 42 | } 43 | } 44 | 45 | #Gathers OS version 46 | $OSVersion = (Get-WmiObject -Class win32_operatingsystem).version 47 | 48 | #-----------------------------------------------------------[Execution]------------------------------------------------------------ 49 | 50 | 51 | try 52 | { 53 | If($OSVersion -gt '10.*') 54 | { 55 | Disable-WindowsOptionalFeature -Online -FeatureName smb1protocol -NoRestart -ErrorAction Stop 56 | Write-Verbose -Message 'Disabling... SMB1 Protocol. Restart to finish disabling SMB1.' 57 | } 58 | ElseIf($OSVersion -lt '10.*') 59 | { 60 | & "$env:windir\system32\sc.exe" config lanmanworkstation depend= bowser/mrxsmb20/nsi 61 | & "$env:windir\system32\sc.exe" config mrxsmb10 start= disabled 62 | Write-Verbose -Message 'Disabling... SMB1 Protocol. Restart to finish disabling SMB1.' 63 | } 64 | } 65 | 66 | catch [System.Runtime.InteropServices.COMException] 67 | { 68 | [Management.Automation.ErrorRecord]$e = $_ 69 | 70 | $info = [PSCustomObject]@{ 71 | Exception = $e.Exception.Message 72 | } 73 | 74 | 75 | $info 76 | } 77 | -------------------------------------------------------------------------------- /Other/Disk_Cleanup_C_drive.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 1 2 | Function Cleanup { 3 | function global:Write-Verbose ([string]$Message) 4 | 5 | { # check $VerbosePreference variable, and turns -Verbose on 6 | if ($VerbosePreference -ne 'SilentlyContinue') { 7 | Write-Host -Object " $Message" -ForegroundColor 'Yellow' 8 | } 9 | } 10 | 11 | $OperatingSystemVersion = (Get-WmiObject -Class Win32_OperatingSystem).Version 12 | 13 | $VerbosePreference = 'Continue' 14 | $DaysToDelete = 7 15 | $LogDate = Get-Date -Format 'MM-d-yy-HH' 16 | $objShell = New-Object -ComObject Shell.Application 17 | $objFolder = $objShell.Namespace(0xA) 18 | $ErrorActionPreference = 'silentlycontinue' 19 | 20 | Start-Transcript -Path C:\Windows\Temp\$LogDate.log 21 | 22 | ## Cleans all code off of the screen. 23 | Clear-Host 24 | 25 | $Before = Get-WmiObject Win32_LogicalDisk | 26 | Where-Object -FilterScript { 27 | $_.DriveType -eq '3' 28 | } | 29 | Select-Object -Property SystemName, 30 | @{ 31 | Name = 'Drive' 32 | Expression = { 33 | ($_.DeviceID) 34 | } 35 | }, 36 | @{ 37 | Name = 'Size (GB)' 38 | Expression = { 39 | '{0:N1}' -f ($_.Size / 1gb) 40 | } 41 | }, 42 | @{ 43 | Name = 'FreeSpace (GB)' 44 | Expression = { 45 | '{0:N1}' -f ($_.Freespace / 1gb) 46 | } 47 | }, 48 | @{ 49 | Name = 'PercentFree' 50 | Expression = { 51 | '{0:P1}' -f ($_.FreeSpace / $_.Size) 52 | } 53 | } | 54 | Format-Table -AutoSize | 55 | Out-String 56 | 57 | ## Stops the windows update service. 58 | Get-Service -Name wuauserv | Stop-Service -Force -Verbose -ErrorAction SilentlyContinue 59 | ## Windows Update Service has been stopped successfully! 60 | 61 | ## Stops the Microsoft Monitoring service. 62 | Get-Service -Name HealthService | Stop-Service -Force -Verbose -ErrorAction SilentlyContinue 63 | ## Microsoft Monitoring Service has been stopped successfully! 64 | 65 | ## Stops the TrustedInstaller service. 66 | Get-Service -Name TrustedInstaller | Stop-Service -Force -Verbose -ErrorAction SilentlyContinue 67 | ## Windows Update Service has been stopped successfully! 68 | 69 | ## Deletes SCCM Cache. 70 | Get-ChildItem 'c:\Windows\ccmcache\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 71 | Where-Object -FilterScript { 72 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 73 | } | 74 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 75 | 76 | ## Deletes the contents of windows software distribution. 77 | Get-ChildItem 'C:\Windows\SoftwareDistribution\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 78 | Where-Object -FilterScript { 79 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 80 | } | 81 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 82 | ## The Contents of Windows SoftwareDistribution have been removed successfully! 83 | 84 | ## Deletes the contents of Microsoft Monitoring Cache (SCOM Cache). 85 | Get-ChildItem 'C:\Program Files\Microsoft Monitoring Agent\Agent\Health Service State\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 86 | Where-Object -FilterScript { 87 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 88 | } | 89 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 90 | ## The Contents of SCOM Cache have been removed successfully! 91 | 92 | ## Deletes the contents of the Windows Temp folder. 93 | Get-ChildItem 'C:\Windows\Temp\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 94 | Where-Object -FilterScript { 95 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 96 | } | 97 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 98 | ## The Contents of Windows Temp have been removed successfully! 99 | 100 | ## Deletes the contents of TrustedInstaller CBS folder. 101 | Get-ChildItem 'C:\Windows\Logs\CBS\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 102 | Where-Object -FilterScript { 103 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 104 | } | 105 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 106 | ## The Contents of Windows SoftwareDistribution have been removed successfully! 107 | 108 | ## Deletes the contents of Dropbox cache folder. 109 | Get-ChildItem "%HOMEPATH%\Dropbox\.dropbox.cache\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 110 | Where-Object -FilterScript { 111 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 112 | } | 113 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 114 | ## The Contents of Windows SoftwareDistribution have been removed successfully! 115 | 116 | 117 | ## Delets all files and folders in user's Temp folder. 118 | Get-ChildItem 'C:\users\*\AppData\Local\Temp\*' -Recurse -Force -ErrorAction SilentlyContinue | 119 | Where-Object -FilterScript { 120 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 121 | } | 122 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 123 | ## The contents of C:\users\$env:USERNAME\AppData\Local\Temp\ have been removed successfully! 124 | 125 | ## Remove all files and folders in user's Temporary Internet Files. 126 | Get-ChildItem 'C:\users\*\AppData\Local\Microsoft\Windows\Temporary Internet Files\*' ` 127 | -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 128 | Where-Object -FilterScript { 129 | ($_.CreationTime -le $(Get-Date).AddDays( - $DaysToDelete)) 130 | } | 131 | Remove-Item -force -recurse -ErrorAction SilentlyContinue 132 | ## All Temporary Internet Files have been removed successfully! 133 | 134 | ## Removes Internet Explorer suggusted sites file 135 | Get-ChildItem 'C:\Users\*\AppData\Local\Microsoft\Windows\INetCache\Low\SuggestedSites.dat' ` 136 | -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 137 | Where-Object -FilterScript { 138 | ($_.CreationTime -le $(Get-Date).AddDays( - $DaysToDelete)) 139 | } | 140 | Remove-Item -force -recurse -ErrorAction SilentlyContinue 141 | ## Internet Explorer suggusted sites file has been removed successfully! 142 | 143 | ## Cleans IIS Logs if applicable. 144 | Get-ChildItem 'C:\inetpub\logs\LogFiles\*' -Recurse -Force -ErrorAction SilentlyContinue | 145 | Where-Object -FilterScript { 146 | ($_.CreationTime -le $(Get-Date).AddDays( - $DaysToDelete)) 147 | } | 148 | Remove-Item -Force -Verbose -Recurse -ErrorAction SilentlyContinue 149 | ## All IIS Logfiles over x days old have been removed Successfully! 150 | 151 | ## Cleans IIS Logs if applicable. 152 | Get-ChildItem 'C:\inetpub\mailroot\Badmail\*' -Recurse -Force -ErrorAction SilentlyContinue | 153 | Where-Object -FilterScript { 154 | ($_.CreationTime -le $(Get-Date).AddDays( - $DaysToDelete)) 155 | } | 156 | Remove-Item -Force -Verbose -Recurse -ErrorAction SilentlyContinue 157 | ## All IIS Logfiles over x days old have been removed Successfully! 158 | 159 | ## Deletes the Microsoft Azure Extension Logs. 160 | Get-ChildItem 'C:\WindowsAzure\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 161 | Where-Object -FilterScript { 162 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 163 | } | 164 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 165 | 166 | ## Deletes the Microsoft Azure Backup Logs. 167 | Get-ChildItem 'C:\Program Files\Microsoft Azure Recovery Services Agent\Temp\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 168 | Where-Object -FilterScript { 169 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 170 | } | 171 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 172 | 173 | C:\program files\Microsoft Azure Recovery Services Agent\Temp 174 | 175 | ## Clears Windows Defender Logs 176 | Get-ChildItem 'C:\ProgramData\Microsoft\Windows Defender\Scans\History\Results\Resource\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 177 | Where-Object -FilterScript { 178 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 179 | } | 180 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 181 | 182 | ## Clears Windows Error Reporting Reports 183 | Get-ChildItem 'C:\ProgramData\Microsoft\Windows\WER\ReportQueue\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 184 | Where-Object -FilterScript { 185 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 186 | } | 187 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 188 | 189 | ## Clears Windows Error Reporting Reports 190 | Get-ChildItem 'C:\Users\*\AppData\Local\Microsoft\Windows\WER\ReportQueue\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 191 | Where-Object -FilterScript { 192 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 193 | } | 194 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 195 | 196 | ## Cleans VMWare Horizon Logs if applicable. 197 | Get-ChildItem 'C:\ProgramData\Microsoft\Windows Defender\Scans\History\Results\Resource\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 198 | Where-Object -FilterScript { 199 | ($_.CreationTime -lt $(Get-Date).AddDays( -$DaysToDelete)) 200 | } | 201 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 202 | 203 | ## Cleans Datto RMM packages if applicable. 204 | Get-ChildItem 'C:\ProgramData\CentraStage\Packages\*' -Recurse -Force -Verbose -ErrorAction SilentlyContinue | 205 | Where-Object -FilterScript { 206 | ($_.CreationTime -lt $(Get-Date).AddDays( - $DaysToDelete)) 207 | } | 208 | Remove-Item -force -Verbose -recurse -ErrorAction SilentlyContinue 209 | 210 | ## deletes the contents of the recycling Bin. 211 | ## The Recycling Bin is now being emptied! 212 | $objFolder.items() | ForEach-Object -Process { 213 | Remove-Item $_.path -ErrorAction Ignore -Force -Verbose -Recurse 214 | } 215 | ## The Recycling Bin has been emptied! 216 | 217 | ## Runs DISM cleanup 218 | ## Windows 8.1 / Server 2012 R2 / Windows 10 / Server 2016 219 | 220 | 221 | switch -Regex ($OperatingSystemVersion) { 222 | '(^10\.0.*|^6\.3.*)' { 223 | 224 | dism.exe /Online /Cleanup-Image /StartComponentCleanup 225 | } 226 | } 227 | { 228 | continue 229 | } 230 | 231 | switch -Regex ($OperatingSystemVersion) { 232 | '(^10\.0.*)' { 233 | 234 | cleanmgr.exe /verylowdisk /d c 235 | } 236 | } 237 | { 238 | continue 239 | } 240 | 241 | ## Starts the Windows Update Service 242 | Get-Service -Name wuauserv | Start-Service -Verbose 243 | 244 | ## Starts the SCOM Service 245 | Get-Service -Name HealthService | Start-Service -Verbose 246 | 247 | ## Starts the TrustedInstaller Service 248 | Get-Service -Name TrustedInstaller | Start-Service -Verbose 249 | 250 | $After = Get-WmiObject Win32_LogicalDisk | 251 | Where-Object -FilterScript { 252 | $_.DriveType -eq '3' 253 | } | 254 | Select-Object -Property SystemName, 255 | @{ 256 | Name = 'Drive' 257 | Expression = { 258 | ($_.DeviceID) 259 | } 260 | }, 261 | @{ 262 | Name = 'Size (GB)' 263 | Expression = { 264 | '{0:N1}' -f ($_.Size / 1gb) 265 | } 266 | }, 267 | @{ 268 | Name = 'FreeSpace (GB)' 269 | Expression = { 270 | '{0:N1}' -f ($_.Freespace / 1gb) 271 | } 272 | }, 273 | @{ 274 | Name = 'PercentFree' 275 | Expression = { 276 | '{0:P1}' -f ($_.FreeSpace / $_.Size) 277 | } 278 | } | 279 | Format-Table -AutoSize | 280 | Out-String 281 | 282 | ## Sends some before and after: 283 | 284 | HOSTNAME.EXE 285 | Get-Date | Select-Object -Property DateTime 286 | Write-Verbose -Message "Before: $Before" 287 | Write-Verbose -Message "After: $After" 288 | Stop-Transcript 289 | ## Completed Successfully! 290 | 291 | ## Send Email to mailbox 292 | $file = "C:\Windows\Temp\$LogDate.log" 293 | $att = New-Object -TypeName Net.Mail.Attachment -ArgumentList ($file) 294 | $Message = New-Object -TypeName System.Net.Mail.MailMessage 295 | $Message.From = 'DiskCleanup@contoso.com' 296 | $Message.To.Add('Operations@contoso.com') 297 | $Message.Subject = HOSTNAME.EXE 298 | 'Disk Cleanup' 299 | $Message.Body = $Message.Attachments.Add($att) 300 | 301 | $smtp = New-Object -TypeName System.net.Mail.SmtpClient 302 | $smtp.Host = "smtp.contoso.com" 303 | $smtp.UseDefaultCredentials = $true 304 | $smtp.Send($Message) 305 | } 306 | Cleanup 307 | -------------------------------------------------------------------------------- /Other/DownloadAndUnzipGitRepo.ps1: -------------------------------------------------------------------------------- 1 | # Function to download and unzip a GitHub repository 2 | function DownloadAndUnzipRepository($url, $outputDir) { 3 | # Extract the repository name from the URL 4 | $repoName = [System.IO.Path]::GetFileNameWithoutExtension($url.Split('/')[-1]) 5 | 6 | # Create the output directory if it doesn't exist 7 | if (-not (Test-Path $outputDir)) { 8 | New-Item -ItemType Directory -Force -Path $outputDir | Out-Null 9 | } 10 | 11 | # Download the zip file 12 | $zipFilePath = Join-Path -Path $outputDir -ChildPath "$repoName.zip" 13 | Invoke-WebRequest -Uri $url -OutFile $zipFilePath 14 | 15 | # Unzip the file 16 | Expand-Archive -Path $zipFilePath -DestinationPath $outputDir 17 | 18 | # Remove the zip file 19 | Remove-Item -Path $zipFilePath 20 | 21 | # Remove non-Markdown files 22 | $markdownFiles = Get-ChildItem -Path $outputDir -Filter "*.md" -Recurse 23 | $nonMarkdownFiles = Get-ChildItem -Path $outputDir -Exclude $markdownFiles -Recurse 24 | $nonMarkdownFiles | Remove-Item -Force -Recurse 25 | } 26 | 27 | # URLs of the GitHub repositories 28 | $repo1Url = "https://github.com/MicrosoftDocs/azure-docs/archive/master.zip" 29 | $repo2Url = "https://github.com/MicrosoftDocs/architecture-center/archive/master.zip" 30 | 31 | # Output directories for the repositories 32 | $outputDir1 = "./repo1" 33 | $outputDir2 = "./repo2" 34 | 35 | # Download and unzip the repositories 36 | DownloadAndUnzipRepository -url $repo1Url -outputDir $outputDir1 37 | DownloadAndUnzipRepository -url $repo2Url -outputDir $outputDir2 38 | 39 | Write-Host "Repositories downloaded and unzipped successfully!" 40 | -------------------------------------------------------------------------------- /Other/Drain-FailoverClusterNode.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 2 | <# 3 | Author: Luke Murray (Luke.Geek.NZ) 4 | Version: 0.1 5 | Purpose: Drains cluster resources from primary node to secondary. 6 | #> 7 | 8 | Import-Module -Name FailoverClusters 9 | $computer = Get-Content -Path env:computername 10 | $computer = $computer.ToLower() 11 | $destnode = Get-ClusterNode | Select-Object -Property Name 12 | 13 | [string]$drainnode = ($destnode.Name -ne $computer) 14 | 15 | Get-ClusterGroup | 16 | ForEach-Object ` 17 | -Process { 18 | If ($_.Name -ne $computer) 19 | { 20 | Move-ClusterGroup -Name $_.Name -Node $drainnode 21 | } 22 | } 23 | 24 | -Process { 25 | If ($_.Name -ne $computer) 26 | { 27 | Move-ClusterGroup -Name $_.Name -Node $computer 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Other/Drain-NLBNode.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 2 | <# 3 | Author: Luke Murray (Luke.Geek.NZ) 4 | Version: 0.1 5 | Purpose: Stops and drains NLB cluster resources from primary node to secondaries, with a wait time of 30 minutes. 6 | #> 7 | 8 | Import-Module -Name NetworkLoadBalancingClusters 9 | Stop-NLBClusterNode -Drain -Timeout 30 10 | -------------------------------------------------------------------------------- /Other/Enable-SQLPorts.ps1: -------------------------------------------------------------------------------- 1 | function Enable-SQLPorts 2 | { 3 | <# 4 | .SYNOPSIS 5 | Enables Microsoft SQL Server Firewall Ports 6 | .EXAMPLE 7 | Enable-SQLPorts 8 | 9 | #> 10 | 11 | #Enabling SQL Server Ports 12 | New-NetFirewallRule -DisplayName 'SQL Server' -Direction Inbound -Protocol TCP -LocalPort 1433 -Action allow 13 | New-NetFirewallRule -DisplayName 'SQL Admin Connection' -Direction Inbound -Protocol TCP -LocalPort 1434 -Action allow 14 | New-NetFirewallRule -DisplayName 'SQL Database Management' -Direction Inbound -Protocol UDP -LocalPort 1434 -Action allow 15 | New-NetFirewallRule -DisplayName 'SQL Service Broker' -Direction Inbound -Protocol TCP -LocalPort 4022 -Action allow 16 | New-NetFirewallRule -DisplayName 'SQL Debugger/RPC' -Direction Inbound -Protocol TCP -LocalPort 135 -Action allow 17 | #Enabling SQL Analysis Ports 18 | New-NetFirewallRule -DisplayName 'SQL Analysis Services' -Direction Inbound -Protocol TCP -LocalPort 2383 -Action allow 19 | New-NetFirewallRule -DisplayName 'SQL Browser' -Direction Inbound -Protocol TCP -LocalPort 2382 -Action allow 20 | #Enabling Misc. Applications 21 | New-NetFirewallRule -DisplayName 'HTTP' -Direction Inbound -Protocol TCP -LocalPort 80 -Action allow 22 | New-NetFirewallRule -DisplayName 'SSL' -Direction Inbound -Protocol TCP -LocalPort 443 -Action allow 23 | New-NetFirewallRule -DisplayName 'SQL Server Browse Button Service' -Direction Inbound -Protocol UDP -LocalPort 1433 -Action allow 24 | #Enable Windows Firewall 25 | Set-NetFirewallProfile -DefaultInboundAction Block -DefaultOutboundAction Allow -NotifyOnListen True -AllowUnicastResponseToMulticast True 26 | } 27 | 28 | Enable-SQLPorts 29 | -------------------------------------------------------------------------------- /Other/Event_Logs.ps1: -------------------------------------------------------------------------------- 1 | # Remember, the -computername parameter requires PowerShell 2.0 or later. 2 | # With Vista/2008-R2 and later machines, use Get-WinEvent instead. 3 | 4 | # To see a list of local event logs and show their important configuration settings: 5 | 6 | get-eventlog -list 7 | 8 | # To show the last 20 events from the System log: 9 | 10 | get-eventlog -log system -newest 20 11 | 12 | # To show only warning and error events from the last 500 events in the System log: 13 | 14 | get-eventlog -log system -newest 500 | 15 | where-object {$_.EntryType -match "^Warning|^Error"} 16 | 17 | # To list the last 10 user accounts created: 18 | 19 | get-eventlog -log security | 20 | where-object {$_.EventID -match "^624$|^4720$"} | 21 | sort-object -property TimeGenerated | 22 | select-object -last 10 23 | 24 | # To list all system log events between 72 and 48 hours ago, sorted by time: 25 | 26 | 27 | get-eventlog -log system | 28 | where-object {$_.TimeGenerated -gt (get-date).AddHours(-72) -and $_.TimeGenerated -lt (get-date).AddHours(-48)} | 29 | sort-object -property TimeGenerated 30 | 31 | 32 | # To get the last 20 events from all three primary logs: 33 | 34 | $events = get-eventlog -log system -newest 20 35 | $events += get-eventlog -log application -newest 20 36 | $events += get-eventlog -log security -newest 20 37 | $events | 38 | sort-object -property TimeGenerated | 39 | format-table TimeGenerated,EventID,EntryType,Source -auto 40 | 41 | # To clear the System event log: 42 | 43 | $log = ( get-eventlog -list | where {$_.log -eq "System"} ) 44 | $log.Clear() 45 | 46 | 47 | # With PowerShell 2.0 and later, to clear the System and Application logs: 48 | 49 | clear-eventlog -log system,application -computername Server57 50 | 51 | 52 | # If you don't have PowerShell 2.0 or later... 53 | 54 | Function Write-ApplicationLog ($message = "text", $type = "Info", $computer = "localhost") 55 | { 56 | Switch -regex ($type) { 57 | 'error' {$type = 1} 58 | 'warning' {$type = 2} 59 | 'info' {$type = 4} 60 | default {$type = 4} 61 | } 62 | 63 | $WshShell = new-object -com "WScript.Shell" 64 | 65 | $Err = $WshShell.LogEvent($type, $message, $computer) 66 | $Err 67 | } 68 | 69 | write-applicationlog 70 | 71 | 72 | -------------------------------------------------------------------------------- /Other/ExpiryingCertificates.ps1: -------------------------------------------------------------------------------- 1 | 2 | Invoke-Command -ComputerName (Get-ADComputer -LDAPFilter '(&(objectCategory=computer)(operatingSystem=Windows Server*)(!serviceprincipalname=*MSClusterVirtualServer*)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' -Property name | Sort-Object -Property Name).Name -Command { 3 | Get-ChildItem -Path cert:LocalMachine\My -Recurse | 4 | Where-Object -FilterScript { 5 | $_.NotAfter -gt (Get-Date) 6 | } | 7 | Select-Object -Property Subject, FriendlyName, Thumbprint, @{ 8 | Name = 'Expires in (Days)' 9 | Expression = { 10 | ($_.NotAfter).subtract([DateTime]::Now).days 11 | } 12 | } | 13 | Where-Object -Property 'Expires in (Days)' -LT -Value 120 14 | } | Export-Csv -Path c:\temp\ExpiringCertificates.csv 15 | -------------------------------------------------------------------------------- /Other/Export_EventLogs.ps1: -------------------------------------------------------------------------------- 1 | # Config 2 | New-Item c:\temp -ItemType Directory -Force 3 | $logFileName = "Application" # Add Name of the Logfile (System, Application, etc) 4 | $path = "C:\temp\" # Add Path, needs to end with a backsplash 5 |   6 | # do not edit 7 | $exportFileName = $logFileName + (get-date -f yyyyMMdd) + ".evt" 8 | $logFile = Get-WmiObject Win32_NTEventlogFile | Where-Object { $_.logfilename -eq $logFileName } 9 | $logFile.backupeventlog($path + $exportFileName) 10 | 11 | # Config 12 | $logFileName = "System" # Add Name of the Logfile (System, Application, etc) 13 | $path = "C:\temp\" # Add Path, needs to end with a backsplash 14 |   15 | # do not edit 16 | $exportFileName = $logFileName + (get-date -f yyyyMMdd) + ".evt" 17 | $logFile = Get-WmiObject Win32_NTEventlogFile | Where-Object { $_.logfilename -eq $logFileName } 18 | $logFile.backupeventlog($path + $exportFileName) -------------------------------------------------------------------------------- /Other/Get-PublicHoliday.ps1: -------------------------------------------------------------------------------- 1 | $Today = Get-Date 2 | $Year = $Today.Year 3 | $CountryCode = 'NZ' 4 | #read the content from nager.date 5 | $url = "https://date.nager.at/api/v2/publicholidays/$Year/$CountryCode" 6 | Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 7 | $Holidays = Invoke-RestMethod -Method Get -UseBasicParsing -Uri $url 8 | 9 | Write-Output $Holidays 10 | -------------------------------------------------------------------------------- /Other/GetDateAM.ps1: -------------------------------------------------------------------------------- 1 | if ( (Get-Date -UFormat %p) -eq "AM" ) { 2 | Write-Host 'Good Morning' 3 | } #End if 4 | else { 5 | Write-Host 'Good Afternoon' 6 | } #end else -------------------------------------------------------------------------------- /Other/Increases_EphemeralPorts_2016.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Increase Pool Size for Ephemeral TCP Ports 4 | 5 | .DESCRIPTION 6 | This script was created increasing the pool Size for Ephemeral TCP Ports and setting the WaitTimeDelay so that the operating system and applications can reuse the ports. 7 | .NOTES 8 | Version: 1.0 9 | Author: Luke Murray (luke.geek.nz) 10 | Purpose/Change: 11 | Initial script creation - created as a workaround for an issue, with ports not getting released successfully. 12 | 13 | .EXAMPLE 14 | ./Increases_EphemeralPorts_2016.ps1 15 | 16 | #> 17 | 18 | #-----------------------------------------------------------[Execution]------------------------------------------------------------ 19 | 20 | Get-Item 'HKLM:\System\CurrentControlSet\Services\Tcpip\Parameters' | New-ItemProperty -Name MaxUserPort -Value 65534 -Force | Out-Null 21 | Get-Item 'HKLM:\System\CurrentControlSet\Services\Tcpip\Parameters' | New-ItemProperty -Name TcpTimedWaitDelay -Value 30 -Force | Out-Null 22 | Get-Item 'HKLM:\System\CurrentControlSet\Services\Tcpip\Parameters' | New-ItemProperty -Name TcpNumConnections -Value 16777214 -Force | Out-Null 23 | Get-Item 'HKLM:\System\CurrentControlSet\Services\Tcpip\Parameters' | New-ItemProperty -Name TcpMaxDataRetransmissions -Value 5 -Force | Out-Null 24 | Restart-Computer -Force -------------------------------------------------------------------------------- /Other/Install-IIS.ps1: -------------------------------------------------------------------------------- 1 | function Install-IIS 2 | { 3 | <# 4 | .SYNOPSIS 5 | Installs IIS 6 | .EXAMPLE 7 | Install-IIS 8 | 9 | #> 10 | 11 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole 12 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServer 13 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-CommonHttpFeatures 14 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpErrors 15 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpRedirect 16 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-ApplicationDevelopment 17 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-NetFxExtensibility45 18 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-HealthAndDiagnostics 19 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpLogging 20 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-LoggingLibraries 21 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-RequestMonitor 22 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpTracing 23 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-Security 24 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-RequestFiltering 25 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-Performance 26 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerManagementTools 27 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-IIS6ManagementCompatibility 28 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-Metabase 29 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-ManagementConsole 30 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-BasicAuthentication 31 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-WindowsAuthentication 32 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-StaticContent 33 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-DefaultDocument 34 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebSockets 35 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-ApplicationInit 36 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-NetFxExtensibility45 37 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-ASPNET45 38 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-ISAPIExtensions 39 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-ISAPIFilter 40 | Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpCompressionStatic 41 | } 42 | 43 | Install-IIS 44 | -------------------------------------------------------------------------------- /Other/Install-Printer.ps1: -------------------------------------------------------------------------------- 1 |  2 | <# 3 | 4 | Author: Luke Murray (http://Luke.Geek.NZ) 5 | Version: 0.1 6 | 7 | Purpose: To install a network printer for all users, using Windows servers and sets the Default page size from Letter to A4. 8 | The variables will need to be changed depending on your environment. 9 | 10 | #> 11 | 12 | #Sets Printer variables 13 | 14 | $printer = 'PrinterName' 15 | $Driver = 'RICOH PCL6 UniversalDriver V4.11' 16 | $port = '\\Server\Printer' 17 | $PaperSize = 'A4' 18 | 19 | #Creates Printer Port 20 | 21 | try 22 | { 23 | $null = Add-PrinterPort -Name $port -PrinterHostAddress $port -ErrorAction Stop 24 | Write-Verbose -Message "The following port: $port has been created." -Verbose 25 | } 26 | 27 | catch [Microsoft.Management.Infrastructure.CimException] 28 | { 29 | [Management.Automation.ErrorRecord]$e = $_ 30 | 31 | 32 | $info = [PSCustomObject]@{ 33 | Exception = $e.Exception.Message 34 | } 35 | 36 | Write-Verbose -Message $info -Verbose 37 | } 38 | 39 | #Creates new printer using the port created in the last step 40 | 41 | try 42 | { 43 | $null = Add-Printer -Name $printer -DriverName $Driver -PortName $port -ErrorAction Stop 44 | Write-Verbose -Message "The following printer: $printer has been created." -Verbose 45 | } 46 | catch [Microsoft.Management.Infrastructure.CimException] 47 | { 48 | [Management.Automation.ErrorRecord]$e = $_ 49 | 50 | $info = [PSCustomObject]@{ 51 | Exception = $e.Exception.Message 52 | } 53 | 54 | Write-Verbose -Message $info -Verbose 55 | } 56 | 57 | #Sets Printer as Default Printer 58 | 59 | $printer = $printer.Replace('\','\\') 60 | $printobj = (Get-WmiObject -Class win32_printer -Filter "Name='$printer'") 61 | $printobj.SetDefaultPrinter() 62 | 63 | #Configures the Printer to A4 64 | 65 | $objPrinter = Get-PrintConfiguration -PrinterName $printer 66 | $strPaperSize = $objPrinter.PaperSize 67 | 68 | If ($strPaperSize -ne $PaperSize) 69 | { 70 | Set-PrintConfiguration -PrinterName $printer -PaperSize $PaperSize 71 | 72 | $objPrinter = Get-PrintConfiguration -PrinterName $printer 73 | $strPaperSizeUpdated = $objPrinter.PaperSize 74 | $strPaperSizeUpdated 75 | 76 | Write-Verbose -Message "The paper size was changed as follows: 77 | From: $strPaperSize 78 | To: $strPaperSizeUpdated" -Verbose 79 | } 80 | Else 81 | { 82 | Write-Verbose -Message "The following printer: $printer has been created." -Verbose 83 | } -------------------------------------------------------------------------------- /Other/New-EventSource.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Luke Murray (Luke.Geek.NZ) 4 | Version: 0.1 5 | Version History: 6 | 7 | Purpose: Simple 1 liner to create a new Windows Event Log and Source. These sources can then be written to by PowerShell scripts or Applications. 8 | Change the $log - CompanyName variable to be the name of the Event Log name you want to create. 9 | 10 | #> 11 | 12 | $log = CompanyName 13 | New-Eventlog -source "$log" -logname $log 14 | New-Eventlog -source 'Patching' -logname $log 15 | New-Eventlog -source 'Monitoring' -logname $log -------------------------------------------------------------------------------- /Other/PesterTests/Windows10.Test.ps1: -------------------------------------------------------------------------------- 1 | Describe 'SMB1 Check' { 2 | 3 | Context 'Check the SMB1 protocol is enabled' { 4 | 5 | It 'Check the SMB1 protocol is enabled' { 6 | $a = Get-SmbServerConfiguration | Select EnableSMB1Protocol 7 | $a.EnableSMB1Protocol | Should -Be $false 8 | } 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Other/README.md: -------------------------------------------------------------------------------- 1 | ## PowerofTheShell - Other 2 | > This Repository is for random scripts I have created for one task or another, that doesn't fully fit in another folder. 3 | 4 | > I get inspiration and help from the PowerShell community so willing to give back in return, also happy if you fork any of the files - or recommend improvements. 5 | 6 | ## Usage example 7 | 8 | Unless specified otherwise, every script can usually be ran directly from Powershell or the PowerShell ISE as Administrator. 9 | The requirements for each script should be listed in the scripts #requires field. 10 | If the scripts in here become a bit unwieldy I may move them to another folder or category at any time. 11 | 12 | ## Meta 13 | 14 | Luke Murray [Twitter] – [@lukemurraynz](https://twitter.com/lukemurraynz) 15 | Luke Murray [Blog] – (http://luke.geek.nz) 16 | 17 | [https://github.com/lukemurraynz/PowerOfTheShell](https://github.com/lukemurraynz/PowerOfTheShell) 18 | 19 | [https://gist.github.com/lukemurraynz](https://gist.github.com/lukemurraynz) 20 | -------------------------------------------------------------------------------- /Other/Remove-OldModules.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 -Modules PowerShellGet 2 | function Remove-OldModules 3 | { 4 | <# 5 | <# 6 | Author: Luke Murray (Luke.Geek.NZ) 7 | Version: 0.1 8 | Purpose: Basic function to remove old PowerShell modules which are installed 9 | #> 10 | 11 | #> 12 | $Latest = Get-InstalledModule 13 | foreach ($module in $Latest) { 14 | 15 | Write-Verbose -Message "Uninstalling old versions of $($module.Name) [latest is $( $module.Version)]" -Verbose 16 | Get-InstalledModule -Name $module.Name -AllVersions | Where-Object {$_.Version -ne $module.Version} | Uninstall-Module -Verbose 17 | } 18 | } 19 | 20 | Remove-OldModules 21 | -------------------------------------------------------------------------------- /Other/RemoveWhiteSpaceInFilesFirstLetter.ps1: -------------------------------------------------------------------------------- 1 | $regex = "^( +)" 2 | get-childitem -R *.* | foreach { rename-item $_ ($_.Name -Replace $regex,'_') } -------------------------------------------------------------------------------- /Other/RemoveWhiteSpaceInFileswith_.ps1: -------------------------------------------------------------------------------- 1 | dir | 2 | Where-Object { $_.name.Contains(" ") } | 3 | Rename-Item -NewName { $_.name -replace " ","_"} -------------------------------------------------------------------------------- /Other/Resolve-Port.ps1: -------------------------------------------------------------------------------- 1 | function Resolve-Port 2 | { 3 | <# 4 | .SYNOPSIS 5 | Resolves Port Script. Script that checks to see if a server is up and responding to a specific port. 6 | .DESCRIPTION 7 | Detailed Description 8 | .EXAMPLE 9 | Resolve-Port -server Server1 -port 3389 10 | .AUTHOR 11 | Luke Murray (Luke.Geek.NZ) 12 | Copied from: https://social.technet.microsoft.com/Forums/office/en-US/7a3304c7-b564-4acc-ab28-2648a20f4bce/telnet-using-powershell?forum=winserverpowershell and put into a Function. 13 | 14 | #> 15 | param 16 | ( 17 | [Parameter(Position=0)] 18 | [string] 19 | $server = 'Server1', 20 | 21 | [Parameter(Position=1)] 22 | [string] 23 | $port = '3389' 24 | ) 25 | 26 | foreach ($null in $server) { 27 | 28 | If ( Test-Connection -ComputerName $server -Count 1 -Quiet) { 29 | 30 | try { 31 | $null = New-Object -TypeName System.Net.Sockets.TCPClient -ArgumentList $server,$port 32 | $props = @{ 33 | Server = $server 34 | PortOpen = 'Yes' 35 | } 36 | } 37 | 38 | catch { 39 | $props = @{ 40 | Server = $server 41 | PortOpen = 'No' 42 | } 43 | } 44 | } 45 | 46 | Else { 47 | 48 | $props = @{ 49 | Server = $server 50 | PortOpen = 'Server did not respond to ping' 51 | } 52 | } 53 | 54 | New-Object -TypeName PsObject -Property $props 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Other/Run-PowerShellAsAdmin.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Author: Luke Murray (Luke.Geek.NZ) 3 | Version: 0.1 4 | Version History: 5 | Purpose: Elevates Powershell as Admin if not already Admin and runs script. 6 | #> 7 | 8 | if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) 9 | { 10 | if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) 11 | { 12 | $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments 13 | 14 | Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine 15 | 16 | Exit 17 | } 18 | } 19 | 20 | Install-Module AzureRM -------------------------------------------------------------------------------- /Other/ServiceMonitor.ps1: -------------------------------------------------------------------------------- 1 | 2 | $serviceName = 'CSFalconService' 3 | $service = Get-Service -Name $ServiceName 4 | 5 | if ($service.Status -ne 'Running'){ 6 | 7 | [reflection.assembly]::loadwithpartialname('System.Windows.Forms') 8 | [reflection.assembly]::loadwithpartialname('System.Drawing') 9 | $notify = new-object system.windows.forms.notifyicon 10 | $notify.icon = [System.Drawing.SystemIcons]::Error 11 | $notify.visible = $true 12 | $notify.BalloonTipTitle = 'Crowdstrike is NOT running' 13 | $notify.BalloonTipText = 'Crowdstrike is NOT running' 14 | $notify.Text = 'Crowdstrike is NOT running' 15 | $Notify.ShowBalloonTip(2500,$serviceName,"Crowdstrike is NOT running.",[system.windows.forms.tooltipicon]::Info) 16 | 17 | } 18 | 19 | Else 20 | 21 | { 22 | [reflection.assembly]::loadwithpartialname('System.Windows.Forms') 23 | [reflection.assembly]::loadwithpartialname('System.Drawing') 24 | $notify = new-object system.windows.forms.notifyicon 25 | $notify.icon = [System.Drawing.SystemIcons]::Information 26 | $notify.visible = $true 27 | $notify.BalloonTipTitle = 'Crowdstrike is running' 28 | $notify.BalloonTipText = 'Crowdstrike is running' 29 | $notify.Text = 'Crowdstrike is running' 30 | $Notify.ShowBalloonTip(2500,$serviceName,"Crowdstrike is running.",[system.windows.forms.tooltipicon]::Info) 31 | 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Other/Start-DFS Service.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 2 | 3 | <# 4 | .SYNOPSIS 5 | Starts the DFS service 6 | 7 | .DESCRIPTION 8 | Changes the Remote Registry service to Automatic start-up and Start the DFS NameSpace service dependencies, then start the DFS namespace service. 9 | If the service does not start, it will retrieve the last 10 event log items from the DFS log. 10 | 11 | .NOTES 12 | Version: 1.0 13 | Author: Luke Murray (Luke.Geek.NZ) 14 | Creation Date: 20/03/17 15 | Purpose/Change: 16 | 20/03/17 - Initial script development 17 | 11/06/18 - Updated script formatting 18 | 19 | .EXAMPLE 20 | ./Start-DFS-Service.ps1 21 | 22 | #> 23 | 24 | #---------------------------------------------------------[Script Parameters]------------------------------------------------------ 25 | 26 | $ServiceName = 'DFS' 27 | $ErrorActionPreference = 'Stop' 28 | 29 | #-----------------------------------------------------------[Execution]------------------------------------------------------------ 30 | 31 | Try 32 | { 33 | Get-Service -Name RemoteRegistry | Set-Service -StartupType Automatic 34 | } 35 | Catch 36 | { 37 | Write-Verbose -Message 'There is an issue changing the Remote Registry Service to Automatic Startup Type' -Verbose 38 | } 39 | Try 40 | { 41 | $ServiceDependency = Get-Service -Name $ServiceName -DependentServices 42 | $ServiceDependency | Set-Service -StartupType Automatic | Start-Service 43 | Write-Verbose -Message "$ServiceName dependencies have started. Will now try starting the $ServiceName service.." -Verbose 44 | } 45 | catch [Microsoft.PowerShell.Commands.ServiceCommandException] 46 | { 47 | [Management.Automation.ErrorRecord]$e = $_ 48 | 49 | $info = New-Object -TypeName PSObject -Property @{ 50 | Exception = $e.Exception.Message 51 | Reason = $e.CategoryInfo.Reason 52 | Target = $e.CategoryInfo.TargetName 53 | Line = $e.InvocationInfo.ScriptLineNumber 54 | Column = $e.InvocationInfo.OffsetInLine 55 | } 56 | Write-Verbose -Message 'Opps! There was an error:' -Verbose 57 | $info 58 | } 59 | Catch 60 | { 61 | Write-Verbose -Message "There was an issue starting $ServiceName dependencies" -Verbose 62 | } 63 | 64 | try 65 | { 66 | Try 67 | { 68 | Start-Service -Name $ServiceName 69 | Write-Verbose -Message "The $ServiceName service has started." -Verbose 70 | } 71 | Catch 72 | { 73 | Get-WinEvent -LogName Microsoft-Windows-DFSN-Server/Operational | Select-Object -Last 10 74 | } 75 | } 76 | 77 | catch 78 | { 79 | [Management.Automation.ErrorRecord]$e = $_ 80 | 81 | $info = New-Object -TypeName PSObject -Property @{ 82 | Exception = $e.Exception.Message 83 | Reason = $e.CategoryInfo.Reason 84 | Target = $e.CategoryInfo.TargetName 85 | Line = $e.InvocationInfo.ScriptLineNumber 86 | Column = $e.InvocationInfo.OffsetInLine 87 | } 88 | Write-Verbose -Message 'Opps! There was an error:' -Verbose 89 | $info 90 | } 91 | -------------------------------------------------------------------------------- /Other/Start-iSCSI.ps1: -------------------------------------------------------------------------------- 1 | # Check if the script is running with administrative privileges 2 | $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") 3 | if (-not $isAdmin) { 4 | Write-Host "Please run this script with administrative privileges." 5 | exit 6 | } 7 | 8 | # Set the service name 9 | $serviceName = "MSiSCSI" 10 | 11 | # Check if the service exists 12 | $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue 13 | if ($service -eq $null) { 14 | Write-Host "The '$serviceName' service does not exist on this system." 15 | exit 16 | } 17 | 18 | # Check if the service is already running 19 | if ($service.Status -eq "Running") { 20 | Write-Host "The '$serviceName' service is already running." 21 | } else { 22 | # Start the service 23 | Start-Service -Name $serviceName 24 | Write-Host "The '$serviceName' service has been started." 25 | } 26 | 27 | # Set the service startup type to Automatic 28 | Set-Service -Name $serviceName -StartupType Automatic 29 | Write-Host "The '$serviceName' service has been set to Automatic startup." 30 | -------------------------------------------------------------------------------- /Other/StartAppPool.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 2.0 2 | <# 3 | Author: Luke Murray (Luke.Geek.NZ) 4 | Version: 0.1 5 | Purpose: Basic script to start AppPool if stopped. 6 | #> 7 | 8 | $AppPoolName = AppPool 9 | 10 | Import-Module -Name WebAdministration 11 | 12 | if((Get-WebAppPoolState $AppPoolName).Value -ne 'Stopped') 13 | { 14 | Start-WebAppPool -Name $AppPoolName 15 | } 16 | -------------------------------------------------------------------------------- /Other/Terraform-Bootstrap.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Bootstraps Terraform environment and runs specified Terraform commands. 4 | 5 | .DESCRIPTION 6 | This script ensures Terraform is installed, sets up the Terraform workspace, and runs specified Terraform commands. 7 | It supports downloading the latest version of Terraform, creating necessary directories, and copying configuration files. 8 | The script is intended to be used to bootstrap Terraform environments for testing and development purposes and once-off deployments of any code in the Config directory. 9 | https://luke.geek.nz/azure/powershell-terraform-bootstrap/ 10 | 11 | .NOTES 12 | Version: 1.0 13 | Author: luke.geek.nz 14 | Creation Date: 10/01/25 15 | Purpose/Change: 16 | 09/01/25 - Initial script creation 17 | 18 | .PARAMETER terraformPath 19 | The path where Terraform will be installed. 20 | 21 | .PARAMETER terraformVersion 22 | The version of Terraform to install. Defaults to "latest". 23 | 24 | .PARAMETER configPath 25 | The path to the directory containing Terraform configuration files. 26 | 27 | .PARAMETER outputPath 28 | The path to the directory where Terraform will be executed. 29 | 30 | .PARAMETER autoApprove 31 | Automatically approve Terraform apply and destroy actions. 32 | 33 | .EXAMPLE 34 | .\Terraform-Bootstrap.ps1 -terraformPath ".\terraform" -terraformVersion "latest" -configPath ".\config" -outputPath ".\output" 35 | #> 36 | 37 | [CmdletBinding()] 38 | param ( 39 | [Parameter(Mandatory = $false)] 40 | [string]$terraformPath = ".\terraform", 41 | 42 | [Parameter(Mandatory = $false)] 43 | [string]$terraformVersion = "latest", 44 | 45 | [Parameter(Mandatory = $false)] 46 | [string]$configPath = ".\config", 47 | 48 | [Parameter(Mandatory = $false)] 49 | [string]$outputPath = ".\output", 50 | 51 | [Parameter(Mandatory = $false)] 52 | [switch]$autoApprove 53 | ) 54 | 55 | # Function to ensure Terraform is installed 56 | function Install-Terraform { 57 | param ( 58 | [string]$version, 59 | [string]$path 60 | ) 61 | 62 | # Get latest version if not specified 63 | if ($version -eq "latest") { 64 | $versionResponse = Invoke-WebRequest -Uri "https://checkpoint-api.hashicorp.com/v1/check/terraform" 65 | $version = ($versionResponse).Content | ConvertFrom-Json | Select-Object -ExpandProperty current_version 66 | } 67 | 68 | # Check if Terraform is already installed 69 | $tfCommand = Get-Command -Name terraform -ErrorAction SilentlyContinue 70 | if ($tfCommand) { 71 | Write-Verbose "Terraform already installed at $($tfCommand.Path)" 72 | return 73 | } 74 | 75 | # Create tools directory 76 | if (!(Test-Path $path)) { 77 | New-Item -ItemType Directory -Path $path | Out-Null 78 | } 79 | 80 | # Download and extract Terraform 81 | $os = if ($IsWindows) { "windows" } else { if ($IsMacOS) { "darwin" } else { "linux" } } 82 | $arch = if ([System.Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" } 83 | 84 | $url = "https://releases.hashicorp.com/terraform/$($version)/terraform_$($version)_${os}_${arch}.zip" 85 | $zipFile = Join-Path $path "terraform.zip" 86 | $extractPath = Join-Path $path "terraform_$version" 87 | 88 | Write-Verbose "Downloading Terraform from $url" 89 | Invoke-WebRequest -Uri $url -OutFile $zipFile 90 | 91 | Write-Verbose "Extracting Terraform to $extractPath" 92 | Expand-Archive -Path $zipFile -DestinationPath $extractPath -Force 93 | Remove-Item $zipFile 94 | 95 | # Add to PATH 96 | $env:PATH = "$extractPath;$env:PATH" 97 | } 98 | 99 | # Function to run Terraform commands 100 | function Invoke-Terraform { 101 | param ( 102 | [string]$workingDirectory, 103 | [string]$command, 104 | [switch]$autoApprove 105 | ) 106 | 107 | Push-Location $workingDirectory 108 | try { 109 | # Initialize 110 | Write-Host "Initializing Terraform..." -ForegroundColor Green 111 | terraform init 112 | 113 | # Run specified command 114 | Write-Host "Running terraform $command..." -ForegroundColor Green 115 | if ($command -eq "apply" -or $command -eq "destroy") { 116 | terraform plan -out=tfplan 117 | 118 | if (!$autoApprove) { 119 | $confirmation = Read-Host "Do you want to proceed with terraform $command? (y/n)" 120 | if ($confirmation -ne 'y') { 121 | Write-Host "Operation cancelled" -ForegroundColor Yellow 122 | return 123 | } 124 | } 125 | 126 | if ($command -eq "apply") { 127 | terraform apply -auto-approve tfplan 128 | } 129 | else { 130 | terraform destroy -auto-approve 131 | } 132 | } 133 | else { 134 | terraform $command 135 | } 136 | } 137 | finally { 138 | Pop-Location 139 | } 140 | } 141 | 142 | # Main script 143 | try { 144 | # Create required directories 145 | if (!(Test-Path $configPath)) { 146 | New-Item -ItemType Directory -Path $configPath -Force | Out-Null 147 | Write-Host "Config directory created at $configPath. Please place Terraform files into this directory and press any key to continue..." -ForegroundColor Yellow 148 | Read-Host 149 | } 150 | if (!(Test-Path $outputPath)) { 151 | New-Item -ItemType Directory -Path $outputPath -Force | Out-Null 152 | } 153 | 154 | # Install Terraform 155 | Write-Host "Ensuring Terraform is installed..." -ForegroundColor Green 156 | Install-Terraform -version $terraformVersion -path $terraformPath 157 | 158 | # Copy Terraform files from config to output directory 159 | Write-Host "Setting up Terraform workspace..." -ForegroundColor Green 160 | 161 | # Convert to absolute paths 162 | $configPathFull = Resolve-Path $configPath -ErrorAction Stop 163 | $outputPathFull = Resolve-Path $outputPath -ErrorAction Stop 164 | 165 | Write-Verbose "Config Path: $configPathFull" 166 | Write-Verbose "Output Path: $outputPathFull" 167 | 168 | $configFiles = Get-ChildItem -Path $configPathFull -Recurse -File -Filter "*.tf" -ErrorAction Stop 169 | $varFiles = Get-ChildItem -Path $configPathFull -Recurse -File -Filter "*.tfvars" -ErrorAction Stop 170 | 171 | Write-Verbose "Found $($configFiles.Count) .tf files" 172 | 173 | foreach ($file in $configFiles) { 174 | Write-Verbose "Processing file: $($file.FullName)" 175 | 176 | # Verify source file 177 | if (!(Test-Path $file.FullName)) { 178 | Write-Error "Source file not found: $($file.FullName)" 179 | continue 180 | } 181 | 182 | # Check file content 183 | $content = Get-Content $file.FullName -Raw 184 | if ([string]::IsNullOrWhiteSpace($content)) { 185 | Write-Warning "File is empty: $($file.FullName)" 186 | continue 187 | } 188 | 189 | Write-Host "Copying $($file.Name) to $outputPathFull" -ForegroundColor Green 190 | Copy-Item -Path $file.FullName -Destination $outputPathFull -Force 191 | 192 | # Verify copy succeeded 193 | $destFile = Join-Path $outputPathFull $file.Name 194 | if (!(Test-Path $destFile)) { 195 | Write-Error "Failed to copy file to: $destFile" 196 | } 197 | } 198 | 199 | foreach ($file in $varFiles) { 200 | Write-Verbose "Processing var file: $($file.FullName)" 201 | Write-Host "Copying $($file.Name) to $outputPathFull" -ForegroundColor Green 202 | Copy-Item -Path $file.FullName -Destination $outputPathFull -Force 203 | } 204 | 205 | 206 | # Run Terraform 207 | Write-Host "Running Terraform..." -ForegroundColor Green 208 | Invoke-Terraform -workingDirectory $outputPath -command "apply" -autoApprove:$autoApprove 209 | 210 | } 211 | catch { 212 | Write-Error "Error occurred: $_" 213 | exit 1 214 | } 215 | -------------------------------------------------------------------------------- /Other/Update-RoyalFolder.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | This script will mirror the OU structure from the specified root OU to a top level folder in the specified Royal TS document and create Remote Desktop Connection objects for all AD computer accounts meeting specific criterias. 4 | 5 | .Description 6 | This script will mirror the OU structure from the specified root OU to a top level folder in the specified Royal TS document and create Remote Desktop Connection objects for all AD computer accounts meeting specific criterias. 7 | 8 | The criterias is the following: 9 | -The computer object is registered with a Server operating system (the object's "Operatingsystem" LDAP property meets the filter "Windows Server*") 10 | -The computer object is not a Cluster Name Object (the object's "ServicePrincipalName" LDAP property does not contain the word MSClusterVirtualServer) 11 | -The computer account has logged on to the domain in the past X number of days (X is 60 days if the parameter InactiveComputerObjectThresholdInDays is not specified) 12 | 13 | The purpose of this script is to show how the Royal TS PowerShell module available in Royal TS V3 beta can be used to manage a Royal TS document. Thus it must be customized to meet specific needs, the script shows how to configure a couple of Remote Desktop connection properties as an example. 14 | The script is meant to be scheduled, for example by using PowerShell Jobs or Scheduled Tasks, in order to have an updated Royal TS document based on active computer accounts in one or more specified Active Directory OU(s). 15 | For smaller environments it may be appropriate to specify the domain DN as the root OU, but this is not recommended for larger environments. Instead the script may be run multiple times with different OU`s specified as the root OU. 16 | 17 | .Parameter RootOUPath 18 | Specifies the path to the root OU for the OU structure you want to mirror 19 | Example: 'OU=Servers,DC=lab,DC=local' 20 | 21 | .Parameter RoyalDocumentPath 22 | Specifies the path to the Royal TS document you want to mirror the OU struture in. If the document does not exist, it will be created. 23 | Example: 'C:\temp\Servers.rtsz' 24 | 25 | .Parameter RemoveInactiveComputerObjects 26 | Switch parameter to specify whether you want to remove inactive computer objects from the Royal TS document 27 | 28 | .Parameter InactiveComputerObjectThresholdInDays 29 | Specifies the number of days for the threshold defining inactive computer objects. If not specified a default value of 60 days will be used. 30 | 31 | .Parameter UpdateRoyalComputerProperties 32 | Switch parameter to specify whether you want to update the Remote Desktop connection properties. Applies for computer objects both new and already present in the Royal TS document. 33 | The properties to be updated is hard coded to enable Smart sizing and inheritance of credentials from the parent folder. 34 | 35 | .Parameter UpdateRoyalFolderProperties 36 | Switch parameter to specify whether you want to update the Royal Folder properties. Applies for folder objects both new and already present in the Royal TS document. 37 | The properties to be updated is hard coded to enable inheritance of credentials from the parent folder. 38 | 39 | .Parameter RTSPSModulePath 40 | Specifies the path to the Royal TS PowerShell module. If Royal TS V3 beta was installed using the MSI-file, this parameter is not required. 41 | Specify the path if you downloaded and extracted the zip-file version of Royal TS V3 to an alternate location. 42 | 43 | .Parameter ADCredential 44 | Specifies the credential to use when communicating with AD Domain Controllers 45 | 46 | 47 | .Notes 48 | Name: Update-RoyalFolder.ps1 49 | Author: Jan Egil Ring 50 | Date Created: 01 Jan 2015 51 | Last Modified: 02 March 2015, Jan Egil Ring 52 | 53 | .Example 54 | & C:\MyScripts\Update-RoyalFolder.ps1 -RootOUPath 'OU=Servers,DC=lab,DC=local' -RoyalDocumentPath C:\temp\Servers.rtsz 55 | 56 | Mirrors the OU structure in the C:\temp\Servers.rtsz Royal TS document based on computer accounts from the root OU OU=Servers,DC=lab,DC=local 57 | 58 | .Example 59 | & C:\MyScripts\Update-RoyalFolder.ps1 -RootOUPath 'OU=Servers,DC=lab,DC=local' -RoyalDocumentPath C:\temp\Servers.rtsz -RemoveInactiveComputerObjects -UpdateRoyalComputerProperties -InactiveComputerObjectThresholdInDays 30 60 | 61 | Mirrors the OU structure in the C:\temp\Servers.rtsz Royal TS document based on computer accounts from the root OU OU=Servers,DC=lab,DC=local 62 | Removes computer accounts already present in the Royal TS document folder which have not logged on to the domain for the last 10 days. 63 | Enables Smart sizing and inheritance of credentials from the parent folder for existing objects if not already enabled. 64 | 65 | 66 | #> 67 | 68 | #requires -Version 4.0 -Module ActiveDirectory 69 | 70 | [CmdletBinding()] 71 | param ( 72 | [Parameter(Mandatory = $true)] 73 | [string]$RootOUPath, 74 | [string]$ADDomainController, 75 | [string]$RoyalDocumentPath = (Join-Path -Path $env:USERPROFILE -ChildPath ('Documents\' + $env:USERDOMAIN + '.rtsz')), 76 | [switch]$RemoveInactiveComputerObjects, 77 | [string]$InactiveComputerObjectThresholdInDays = '60', 78 | [switch]$UpdateRoyalComputerProperties, 79 | [switch]$UpdateRoyalFolderProperties, 80 | [string]$RTSPSModulePath = (Join-Path -Path ${env:ProgramFiles(x86)} -ChildPath 'code4ward.net\Royal TS V4\RoyalDocument.PowerShell.dll'), 81 | [pscredential]$ADCredential 82 | ) 83 | 84 | 85 | # Verify that the Royal TS PowerShell module is present at the specified path. 86 | # In the beta version of Royal TS V3, the module is not available in $env:PSModulePath and thus needs to be imported explicitly 87 | if (-not (Test-Path -Path $RTSPSModulePath)) { 88 | 89 | throw "Royal TS PowerShell module does not exist at $RTSPSModulePath" 90 | 91 | } 92 | 93 | # Import the Royal TS PowerShell module 94 | if (-not (Get-Module -Name RoyalDocument.PowerShell)) { 95 | 96 | Import-Module $RTSPSModulePath 97 | 98 | } 99 | 100 | if (-not $ADDomainController) { 101 | 102 | $ADDomainController = $env:USERDNSDOMAIN 103 | 104 | } 105 | 106 | # Adding -Credential to AD-cmdlets (if specified) 107 | 108 | if ($ADCredential) { 109 | 110 | $PSDefaultParameterValues.Add("*-AD*:Credential",$ADCredential) 111 | 112 | } 113 | 114 | # Create a new RoyalStore in memory 115 | $Store = New-RoyalStore -UserName ($env:USERDOMAIN + '\' + $env:USERNAME) 116 | 117 | # Create the new document if it does not exist 118 | if (-not (Test-Path -Path $RoyalDocumentPath)) { 119 | 120 | $RoyalDocument = New-RoyalDocument -Name $env:USERDOMAIN -FileName $RoyalDocumentPath -Store $Store 121 | 122 | # Store the new document to disk and close it 123 | Out-RoyalDocument -Document $RoyalDocument 124 | Close-RoyalDocument -Document $RoyalDocument 125 | 126 | } 127 | 128 | # Open the Royal TS document 129 | $RoyalDocument = Open-RoyalDocument -FileName $RoyalDocumentPath -Store $Store 130 | 131 | # Define helper functions 132 | function Update-RoyalFolder ($SearchBase, $FolderName) 133 | { 134 | 135 | $Date = Get-Date 136 | 137 | 138 | 139 | $ADObjects = Get-ADComputer -Server $ADDomainController -searchbase $SearchBase -SearchScope OneLevel -LDAPFilter "(&(objectCategory=computer)(operatingSystem=Windows Server*)(!serviceprincipalname=*MSClusterVirtualServer*))" -Properties description,lastlogondate | 140 | Where-Object lastlogondate -gt $Date.AddDays(-$InactiveComputerObjectThresholdInDays) | 141 | Select-Object -Property name,dnshostname,lastlogondate,description | 142 | Sort-Object -Property name 143 | 144 | 145 | 146 | $RoyalFolder = Get-RoyalObject -Type RoyalFolder -Store $Store | Where-Object {$_.Name -eq $FolderName -and $_.Description -eq $SearchBase} 147 | 148 | $RDSConnections = Get-RoyalObject -Type RoyalRDSConnection -Store $Store | 149 | Where-Object {$_.ParentId -eq $RoyalFolder.Id.Guid} 150 | 151 | $RDSConnectionNames = $RDSConnections | Select-Object -ExpandProperty name 152 | 153 | 154 | if ($ADObjects) { 155 | 156 | Write-Verbose -Message "Updating $($FolderName)" 157 | 158 | foreach ($ADObject in $ADObjects) 159 | { 160 | 161 | if ($ADObject.Name -notin $RDSConnectionNames) { 162 | 163 | $RDS = New-RoyalObject -Folder $RoyalFolder -Type RoyalRDSConnection -Name $ADObject.Name -Description $ADObject.Description 164 | $null = Set-RoyalObjectValue -Object $RDS -Property "URI" -Value $ADObject.DnsHostName 165 | 166 | Write-Verbose -Message "Added $($ADObject.Name)" 167 | 168 | if ($UpdateRoyalComputerProperties) { 169 | 170 | Update-RoyalComputerProperty -ComputerObject $RDS 171 | 172 | } 173 | 174 | 175 | } else { 176 | 177 | if ($UpdateRoyalComputerProperties) { 178 | 179 | Update-RoyalComputerProperty 180 | 181 | 182 | } 183 | 184 | 185 | } 186 | 187 | } 188 | 189 | } else { 190 | 191 | Write-Verbose -Message "No computer objects matching the selected filter found in OU $($FolderName)" 192 | 193 | } 194 | 195 | 196 | if ($RDSConnections -and $RemoveInactiveComputerObjects) { 197 | 198 | Write-Verbose -Message "Checking OU $($FolderName) for inactive computer objects" 199 | 200 | foreach ($item in $RDSConnections) { 201 | 202 | if ($item.Name -notin $ADObjects.Name) { 203 | 204 | Write-Verbose -Message "Removing inactive computer object $($item.Name)" 205 | 206 | $null = Remove-RoyalObject -Object $item 207 | 208 | } 209 | } 210 | 211 | } 212 | 213 | } 214 | 215 | 216 | function Test-RoyalFolder ($Description, $FolderName, $ParentFolderName, $ParentFolderNameDescription) 217 | { 218 | 219 | $RoyalFolder = Get-RoyalObject -Type RoyalFolder -Store $Store | Where-Object {$_.Name -eq $FolderName -and $_.Description -eq $Description} 220 | 221 | 222 | if (-not ($RoyalFolder)) { 223 | 224 | if ($ParentFolderName) { 225 | 226 | $RoyalFolderParent = Get-RoyalObject -Type RoyalFolder -Store $Store | Where-Object {$_.Name -eq $ParentFolderName -and $_.Description -eq $ParentFolderNameDescription} 227 | 228 | if (-not ($RoyalFolderParent)) { 229 | 230 | throw "Parent does not exists" 231 | 232 | } 233 | 234 | $RoyalFolder = New-RoyalObject -Folder $RoyalFolderParent -Type RoyalFolder -Name $FolderName -Description $Description 235 | 236 | } else { 237 | 238 | $RoyalFolder = New-RoyalObject -Folder $RoyalDocument -Type RoyalFolder -Name $FolderName -Description $Description 239 | 240 | } 241 | 242 | } 243 | 244 | if ($UpdateRoyalFolderProperties) { 245 | 246 | if ($RoyalFolder.CredentialFromParent -ne $true) { 247 | 248 | Write-Verbose -Message "Enabling CredentialFromParent for folder $FolderName" 249 | 250 | $RoyalFolder.CredentialFromParent = $true 251 | 252 | } 253 | 254 | } 255 | 256 | } 257 | 258 | 259 | function Update-RoyalComputerProperty { 260 | 261 | param ( 262 | $ComputerObject 263 | ) 264 | 265 | if ($ComputerObject) { 266 | 267 | $item = $ComputerObject 268 | 269 | } else { 270 | 271 | $item = $RDSConnections | 272 | where-object {$_.ParentId -eq $RoyalFolder.Id.Guid -and $_.Name -eq $ADObject.Name} 273 | 274 | } 275 | 276 | Write-Verbose -Message "Checking for computer object $($item.Name) for property compliance" 277 | 278 | if ($item.SmartSizing -ne $true) { 279 | 280 | Write-Verbose -Message "Enabling SmartSizing for computer object $($item.Name)" 281 | 282 | $item.Smartsizing = $true 283 | 284 | } 285 | 286 | if ($item.CredentialFromParent -ne $true) { 287 | 288 | Write-Verbose -Message "Enabling CredentialFromParent for computer object $($item.Name)" 289 | 290 | $item.CredentialFromParent = $true 291 | 292 | } 293 | 294 | 295 | 296 | } 297 | 298 | 299 | try 300 | { 301 | $RootOU = Get-ADOrganizationalUnit -Server $ADDomainController -Identity $RootOUPath -ErrorAction Stop 302 | } 303 | catch 304 | { 305 | 306 | $error[0].Exception 307 | throw "An error occured while retrieving the root OU" 308 | 309 | 310 | } 311 | 312 | 313 | Test-RoyalFolder -FolderName $RootOU.Name -Description $RootOU.DistinguishedName 314 | 315 | Update-RoyalFolder -SearchBase $RootOU.DistinguishedName -FolderName $RootOU.Name 316 | 317 | $OUs = Get-ADOrganizationalUnit -Server $ADDomainController -SearchBase $RootOU -Filter * -SearchScope OneLevel | Select-Object Name,DistinguishedName 318 | 319 | 320 | if ($OUs) { 321 | 322 | foreach ($OU in $OUs) { 323 | 324 | $ParentOU = $RootOU 325 | 326 | Test-RoyalFolder -FolderName $OU.Name -Description $OU.DistinguishedName -ParentFolderName $ParentOU.Name -ParentFolderNameDescription $ParentOU.DistinguishedName 327 | 328 | Update-RoyalFolder -SearchBase $OU.DistinguishedName -FolderName $OU.Name 329 | 330 | $ChildOUs = Get-ADOrganizationalUnit -Server $ADDomainController -SearchBase $OU.DistinguishedName -Filter * -SearchScope OneLevel | Select-Object Name,DistinguishedName 331 | 332 | $ChildOUsToProcess = $true 333 | 334 | while ($ChildOUsToProcess) 335 | { 336 | 337 | $ChildOUsToProcess = @() 338 | 339 | foreach ($ChildOU in $ChildOUs) { 340 | 341 | $ParentOU = $OU 342 | 343 | Test-RoyalFolder -FolderName $ChildOU.Name -Description $ChildOU.DistinguishedName -ParentFolderName $ParentOU.Name -ParentFolderNameDescription $ParentOU.DistinguishedName 344 | 345 | Update-RoyalFolder -SearchBase $ChildOU.DistinguishedName -FolderName $ChildOU.Name 346 | 347 | $ChildOUsToProcess += Get-ADOrganizationalUnit -Server $ADDomainController -SearchBase $ChildOU.DistinguishedName -Filter * -SearchScope OneLevel | Select-Object Name,DistinguishedName 348 | 349 | } #end foreach $ChildOU 350 | 351 | $ChildOUs = $ChildOUsToProcess 352 | 353 | 354 | 355 | } #end while 356 | 357 | } #end foreach $OU 358 | 359 | } #end if $OUs 360 | 361 | # Store the updated document to disk and close it 362 | Out-RoyalDocument -Document $RoyalDocument 363 | Close-RoyalDocument -Document $RoyalDocument 364 | -------------------------------------------------------------------------------- /Other/vCenter_Postqres_Backup.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Backup a VMWare vCenter Postqres DB 4 | .DESCRIPTION 5 | Backup a VMWare vCenter Postqres DB. Quick/Basic script to be ran from a Scheduled Task using the VMWare Postqres Backup scripts - https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2091961 6 | Change the $postqrespwd variable to match your vCenter Postqres password that can be found here: C:\ProgramData\VMware\vCenterServer\cfg\vmware-vpx\vcdb.properties 7 | .AUTHOR 8 | Luke Murray (Luke.geek.nz) 9 | 10 | #> 11 | $Date = Get-Date -format m 12 | $postqrespwd = 'VCDBPassword' 13 | & 'C:\Program Files\VMware\vCenter Server\python\python.exe' C:\temp\2091961_windows_backup_restore\backup_win.py -p $postqrespwd -f C:\Backups\backup_VCDB.$Date.bak 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerofTheShell 2 | > This Repository is for random Knicks and knacks - in relation to PowerShell (Windows based) scripts I have created for one task or another. 3 | 4 | > I get inspiration and help from the PowerShell community so willing to give back in return, also happy if you fork any of the files - or recommend improvements. 5 | 6 | ## Usage example 7 | 8 | Unless specified otherwise, every script can usually be ran directly from Powershell or the PowerShell ISE as Administrator. 9 | 10 | ## Meta 11 | 12 | Luke Murray [Twitter] – [@lukemurraynz](https://twitter.com/lukemurraynz) 13 | Luke Murray [Blog] – (http://luke.geek.nz) 14 | 15 | [https://github.com/lukemurraynz/PowerOfTheShell](https://github.com/lukemurraynz/PowerOfTheShell) 16 | 17 | [https://gist.github.com/lukemurraynz](https://gist.github.com/lukemurraynz) 18 | -------------------------------------------------------------------------------- /SCCM/Create-UserDeviceCollections.ps1: -------------------------------------------------------------------------------- 1 | #requires -Modules ActiveDirectory, ConfigurationManager 2 | #requires -Version 2.0 3 | 4 | <# 5 | 6 | Author: Luke Murray (Luke.geek.nz) 7 | Version: 0.1 8 | Version History: 9 | 10 | Purpose: To create user collections in Configuration Manager that are based on Department. 11 | 12 | This requires the Department field to be added to Active Directory User discovery in Configuration Manager. 13 | 14 | #> 15 | 16 | #Imports the Configuration Manager Module. If the Configuration Manager console is not installed in the default path, this will need to be changed. You will also need to launch PowerShell from within Configuration Manager first. 17 | Import-Module -Name "${env:ProgramFiles(x86)}\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" 18 | #Specifies the site code - this will need to be modified, depending on the site code you are using in your environment. 19 | $sitecode = 'EXM:' 20 | #Sets the location of the script to UserCollection and then creates a Departments folder. You can rename "Departments" to suit your environment. 21 | 22 | Set-Location $sitecode 23 | New-Item -Name 'UserCollection\Departments' 24 | 25 | # Helper function for creating a collection refresh schedule 26 | Function New-RandomSchedule() { 27 | "01/01/2000 $((Get-Random -Min 0 -Max 23).ToString('00')):$((Get-Random -Min 0 -Max 59).ToString('00')):00" 28 | } 29 | 30 | $Schedule = New-CMSchedule -Start (New-RandomSchedule) -RecurInterval Days -RecurCount 7 31 | 32 | #Sets the Active Directory parameters, this needs to be modified for your environment, your domain root or Domain Controller, the OU of the user accounts you want to query to obtain the departments. 33 | $ADUserParams = @{ 34 | #Enter in the Domain Name in the server field, ie domain.local 35 | 'Server' = 'DOMAINNAMEHERE' 36 | #Enter in the OU that you will searhe Users, in the Searchbase field below: 37 | 'Searchbase' = 'OU=ADUsers,DC=DOMAIN,DC=DOMAIN' 38 | 'Searchscope' = 'Subtree' 39 | 'Filter' = 'Enabled -eq $True' 40 | 'Properties' = 'Department' 41 | } 42 | 43 | $departments = Get-Aduser @ADUserParams | select-object -ExpandProperty Department -Unique 44 | foreach ($department in $departments) { 45 | $UserCollection = New-CMUserCollection -Name $department -Comment "This is a user collection, based off the Department name of $department which is from the Active Directory Department field." -LimitingCollectionName 'All Users' -RefreshType Periodic -RefreshSchedule $Schedule 46 | Add-CMUserCollectionQueryMembershipRule -CollectionName $department -RuleName $department -QueryExpression ("select SMS_R_USER.ResourceID,SMS_R_USER.ResourceType,SMS_R_USER.Name,SMS_R_USER.UniqueUserName,SMS_R_USER.WindowsNTDomain from SMS_R_User where SMS_R_User.department = `"$department`" order by SMS_R_User.Name") 47 | Move-CMObject -InputObject $UserCollection -FolderPath "$sitecode\UserCollection\Departments" 48 | } --------------------------------------------------------------------------------