Terraform - Azure - azurerm_virtual_machine_extension - multiline Powershell script - terraform-provider-azure

I am preparing VM deployment, and on VMs I need to run some powershell command lets. I need to install Windows Server role, and initialize new ssd disk. I am working on Azure cloud, Terraform deployment has been tested, works as expected, VM is deployed with all required configuration, but facing some problems during multiline powershell commands. I use terraform resource azurerm_virtual_machine_extension, it works when I am trying to install/use one block of code, for example for Windows server role installation. I don't want to use storage account and container and .ps1 script file uploaded to storage container, I need to use inline powershell code. My terraform clode below.
resource "azurerm_virtual_machine_extension" "vmext" {
name = "vmext"
virtual_machine_id = azurerm_windows_virtual_machine.app_vm.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
settings = <<SETTINGS
{
"commandToExecute": "powershell -ExecutionPolicy Unrestricted Install-windowsfeature -name RoleName -IncludeManagementTools; powershell -ExecutionPolicy Unrestricted Get-Disk | Where-Object -FilterScript {$_.PartitionStyle -eq 'RAW'} | Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel 'disk2' -Confirm:$false"
}
SETTINGS
}

Try this:
resource "azurerm_virtual_machine_extension" "vmext" {
name = "vmext"
virtual_machine_id = azurerm_windows_virtual_machine.app_vm.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
settings = <<SETTINGS
{
"commandToExecute": <<EOF
powershell -ExecutionPolicy Unrestricted Install-windowsfeature -name RoleName -IncludeManagementTools
powershell -ExecutionPolicy Unrestricted Get-Disk | Where-Object -FilterScript {$_.PartitionStyle -eq 'RAW'} | Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel 'disk2' -Confirm:$false"
EOF
}
SETTINGS
}
Hope this helps!

Related

Docker powershell Install-Module partially added module functions of Microsoft graph

I was trying to build my own custom docker image with azure-powershell docker base image. As an additional feature i need to add Microsoft Graph modules (specially https://www.powershellgallery.com/packages/Microsoft.Graph.Identity.SignIns/1.10.0) in to the docker image. below are some code that i have written to achieve it.
Dockerfile
FROM mcr.microsoft.com/powershell:ubuntu-22.04
RUN pwsh -Command Set-PSRepository -Name PSGallery -InstallationPolicy Trusted && \
pwsh -Command Install-Module -Name Microsoft.Graph.Identity.SignIns -Scope AllUsers -Repository PSGallery && \
pwsh -Command Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted
ADD deployment/powershell/Main.ps1 Main.ps1
CMD ["pwsh", "-File", "Main.ps1"]
Main.ps1
Update-MgPolicyB2CAuthenticationMethodPolicy
Modules path:
ERROR
Line |
32 | Update-MgPolicyB2CAuthenticationMethodPolicy
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The term 'Update-MgPolicyB2CAuthenticationMethodPolicy' is not
| recognized as a name of a cmdlet, function, script file, or
| executable program. Check the spelling of the name, or if a
| path was included, verify that the path is correct and try
| again.
Info
powershell version: 7.2.5
Find-Module log
Name : Microsoft.Graph.Identity.SignIns
Path : /usr/local/share/powershell/Modules/Microsoft.Graph.Identit
y.SignIns/1.10.0/Microsoft.Graph.Identity.SignIns.psd1
Description : Microsoft Graph PowerShell Cmdlets
Guid : 60f889fa-f873-43ad-b7d3-b7fc1273a44f
Version : 1.10.0
ModuleBase : /usr/local/share/powershell/Modules/Microsoft.Graph.Identit
y.SignIns/1.10.0
ModuleType : Script
PrivateData : {PSData, Profiles}
AccessMode : ReadWrite
ExportedAliases : {}
ExportedCmdlets : {}
ExportedFunctions : {[Confirm-MgInformationProtectionSignature,
Confirm-MgInformationProtectionSignature],
[Confirm-MgRiskyServicePrincipalCompromised,
Confirm-MgRiskyServicePrincipalCompromised],
[Confirm-MgRiskyUserCompromised,
Confirm-MgRiskyUserCompromised],
[Get-MgDataPolicyOperation, Get-MgDataPolicyOperation]…}
ExportedVariables : {}
NestedModules : {}
Question
According to Microsoft.Graph.Identity.SignIns there are many functions present some of the functions worked fine some are not like above. There is no deprecation information given in the docs. What is the main reason for this partial load ?
enter image description here
those commands are available in MS graph powershell beta. so
You need to install the Microsoft.Graph.Beta cmdlets - https://github.com/microsoftgraph/msgraph-sdk-powershell/tree/master

Windows Docker IIS App Pool not able to read certificates from local cert store

I've asp.net MVC website hosted within docker container. The site needs to read the certificates stored on cert:\currentuser\my and present it to the Azure AD for app authentication.
I've loaded the pfx certs on to docker as part of image build per below:
# Install cert, located at certs folder in the host machine, relative to the path of the Solution Dockerfile
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
WORKDIR C:\certs
COPY ./certs .\
RUN Get-ChildItem -File | Foreach { Import-PfxCertificate -Password (ConvertTo-SecureString -String "xyz1234" -AsPlainText -Force) -CertStoreLocation Cert:\CurrentUser\My -FilePath $_.fullname }
Then have this simple test aspx to read the cert by thumprint:
public X509Certificate2 FindCertificateByThumbprint(string findValue, bool validateCertificate)
{
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint,
findValue, validateCertificate);
if (col == null || col.Count == 0)
return null;
return col[0];
}
finally
{
store.Close();
}
}
Note:
On non docker (local laptop), This works perfectly OK for web.
On docker container, console app can find the certificate but not web app.
I tried all these but no luck:
https://newbedev.com/how-to-grant-permission-to-user-on-certificate-private-key-using-powershell
How to Grant permission to user on Certificate private key using powershell?
https://www.codyhosterman.com/2019/06/assigning-read-access-to-windows-private-key/
Feels like I'm missing a step here but not sure what. Has anyone got

Creating registry DWORD entry with PowerShell

I am trying to create registry entries for some time now.
Enviroment:
Offline environment (No Domain)
1 Windows Server 2012 R2
200 Windows 7 clients
The following entry should be created on several computers:
[HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system]
"LocalAccountTokenFilterPolicy"=dword:00000001
For this I would like to use the following script
$Computers = Get-Content "C:\Scripts\Clients.txt"
$Path = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$Name = "LocalAccountTokenFilterPolicy"
$PropertyType = "DWord"
$Value = 1
$results = foreach ($computer in $Computers) {
if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
try {
Set-ItemProperty -Path $path -Name $Name -Value $Value -Type $PropertyType -ErrorAction 'Stop'
$status = "Success"
} catch {
$status = "Failed"
}
} else {
$status = "Unreachable"
}
New-Object -TypeName PSObject -Property #{
'Computer' = $computer
'Status' = $status
}
}
$results | Export-Csv -NoTypeInformation -Path "./error.csv"
The script is executed, no error appears, but the entries were not created.
Where is my error?
Always try a simple 'Get' first, and then progress to testing lines before trying your 'Set'...
So you first test locally on a system, before your foreach invoke, on single system:
`Get-ItemProperty HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy`
If you get a good response like this:
LocalAccountTokenFilterPolicy : 0
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curre
ntVersion\Policies\System
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curre
ntVersion\Policies
PSChildName : System
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Then you've got the right command to work with. Now change the 'Get' to a 'Set' and work out the values LOCALLY.
I think you are close, but missed something in your tests...
Do ONE at a time, locally, first in PowerShell ISE. Then invoke-command to that same single system, then one by one add your tests...
- Patrick Burwell, 25 year Windows and Linux SysAdmin

Simultaneous PowerShell script execution

I have written the following script for SQL patching:
cls
$computers = Get-Content D:\Abhi\Server.txt
foreach ($line in $computers)
{
psexec \\$line -s -u Adminuser -p AdminPassword msiexec /i D:\SQL_PATCH\rsSharePoint.msi SKIPCA=1 /qb
}
My doubt here is to parallelize this script execution on all the servers mentioned in the text file. Meaning, as soon I start the execution of the script, this should initiate the patching activity on the servers simultaneously and also to track the progess on all the servers, as this script is doing now only for one server.
Kindly help me on this.
Thanks Ansgar Wiechers.
This piece of code did it. It helps in executing the .exe simultaneously on all the servers as well as track their status:
cls
$servers = Get-Content 'D:\Abhi\Server.txt'
$servers | ForEach-Object {$comp = $_
Start-Job -ScriptBlock {psexec \\$input -s -u Adminuser -p AdminPassword C:\SQL_PATCH\SQLServer2008R2SP3-KB2979597-x64-ENU.exe /quiet /action=patch /allinstances /IAcceptSQLServerLicenseTerms} -InputObject $comp}
While (Get-Job -State Running)
{
Get-Job | Receive-Job
#Start-Sleep 2
#Write-Host "Waiting for update removal to finish ..."
}
Remove-Job *

VSTS report on Source Control

Is there a way in VSTS 2008 to generate a report on the source control in Team Foundation Server, of what are the files that were changed by user: x for last few days?
Do you need a webpage hosted by SQL Reporting Services, or will any reporting mechanism do? Here's a quick & dirty one:
tfhistory $/project -r -all -version D6/10/2009~ | % {
$user = $_.owner
$date = $_.creationdate
$_.changes | % { $_.item } |
add-member noteproperty user $user -passthru |
add-member noteproperty date $date -passthru
} |
sort #{Expression="User";Ascending=$true},#{Expression="Date";Ascending=$false},#{Expression="ServerItem";Ascending=$true} |
select user, date, serveritem |
out-gridview
(requires the Powershell snapin from TFS Power Tools)

Resources