Trying to Extract Previous Day Azure VM Report but unable to Do via Powershell - azure

I am trying to generate backup report for previous day via Powershell but its not working .Can anyone help me on that .
Below is my Powershell Script
$ErrorActionPreference = "SilentlyContinue"
$report_object =$null
$report_object = #()
$vms = get-azvm | select Name
$acs = Get-AzRecoveryServicesVault
foreach ($ac in $acs){
Set-AzRecoveryServicesVaultContext -Vault $ac
$container_list = Get-AzRecoveryServicesBackupContainer -ContainerType AzureVM
foreach($container_list_iterator in $container_list){
$backup_item = Get-AzRecoveryServicesBackupItem -Container $container_list_iterator -WorkloadType AzureVM

Your code is missing two curly braces (}}) at the end of the code. Is it just a typo? Or is that the reason for you to be unable to extract the report?
I have tried to reproduce the issue to see if I get any exceptions while execution but it all went well as shown in below screenshot.
Can you elaborate on what you meant by "unable to extract the report". Did you receive any error while executing the code? Please provide more details in that context.

Related

Compare two Files and list only the differences of 2nd File using Powershell

I'm trying to get the current list of azure vms on first run of script -> Stores to Storage Account in CSV File
O the 2nd run - Current List should be compared with existing csv file in Storage Account incase of any vms decommisioned that should be recorded and stored in 2nd File in Storage Account
This works fine for me but the issue is when we create a new azure vm which was also gets added to decommission csv list
$Difference = Compare-Object $existingVmCsv $vmrecordFile -Property VmName -PassThru | Select-Object VmName,ResourceGroupName,SubscriptionName
I tried couple of side indicators but dint work
$Difference = Compare-Object -ReferenceObject #($vmrecordFile | Select-Object) -DifferenceObject #($existingVmCsv | Select-Object) -PassThru -Property VmName,ResourceGroupName,SubscriptionName | Where-Object {$_sideIndicator -eq "<="}
$Difference = Compare-Object -ReferenceObject $vmrecordFile -DifferenceObject $existingVmCsv -PassThru -Property VmName,ResourceGroupName,SubscriptionName | Where-Object {$_sideIndicator -eq "<="}
Thank you User Cpt.Whale - Stack Overflow . Posting your suggestions as answer to help other community members.
It seems, you have a typo in a syntax. Object property references should use a "." , like Where-Object { $_.sideIndicator -eq '<=' }
'<=' This indicates that property value appears only in the -ReferenceObject setReferences: powershell - compare two files and update the differences to 2nd file - Stack Overflow , Powershell : How to Compare Two Files, and List Differences | | Dotnet Helpers (dotnet-helpers.com) and compare-object not working : PowerShell (reddit.com)

PowerShell: update O365 AD bulk attributes through csv file

We are trying to bulk update our Azure Active Directory. We have a excel csv list of UserPrincipalNames that we will update the Title, Department, and Office attributes
# Get List of Clinical CMs
$PATH = "C:\Users\cs\Documents\IT Stuff\Project\Azure AD Update\AD-Update-ClinicalCMs-Test.csv"
$CMs = Import-csv $PATH
# Pass CMs into Function
ForEach ($UPN in $CMs) {
# Do AD Update Task Here
Set-Msoluser -UserPrincipalName $UPN -Title "Case Manager" -Department "Clinical" -Office "Virtual"
}
The CSV:
User.1#domain.com
User.2#domain.com
User.3#domain.com
The Set-MsolUser command will work on its own, but it is not working as intended in this For loop. Any help or insight is greatly appreciated
As Jim Xu commented, here my comment as answer.
The input file you show us is not a CSV file, instead, it is a list of UPN values all on a separate line.
To read these values as string array, the easiest thing to is to use Get-Content:
$PATH = "C:\Users\cs\Documents\IT Stuff\Project\Azure AD Update\AD-Update-ClinicalCMs-Test.csv"
$CMs = Get-Content -Path $PATH
Of course, although massive overkill, it can be done using the Import-Csv cmdlet:
$CMs = (Import-Csv -Path $PATH -Header upn).upn

Call Set-AzureRmAppServicePlan cmdlet with arbitrary parameters

I want to call Set-AzureRmAppServicePlan with arbitrary parameters, the list of parameters is defined in runtime and is not set statically.
In other languages like Perl I would use Hash for this, but I get stuck here in Powershell even though I know that Powershell supports HashTables.
Following example does not work
$params = #{}
$params.add('-WorkerSize', 'Small');
$params.add('-NumberofWorkers', '2');
Set-AzureRmAppServicePlan -ResourceGroupName 'RG1' -Name 'AppServicePlna1' $params
I get Set-AzureRmAppServicePlan : Long running operation failed with status 'BadRequest'. error from Azure.
PowerShell does support what you are trying to do. It is known as splatting.
In your case, you have a minor typo. All you need to do is change the $ to an # in this line:
Set-AzureRmAppServicePlan -ResourceGroupName 'RG1' -Name 'AppServicePlna1' $params
So the working version looks like this:
Set-AzureRmAppServicePlan -ResourceGroupName 'RG1' -Name 'AppServicePlna1' #params
The issue is not with PowerShell per say.
Last time I checked you cannot pass 'Parameter key' for an Azure Module command.

I am trying to read the output values from ARM template in post deployment script file. Can you give me the syntax to read those values?

I am trying to read the output values from ARM template in post deployment script file. Can you give me the syntax to read those values?
You could retrieve the out value from a linked template by using reference function.
retrieve the property value with syntax like: "[reference('<name-of-deployment>').outputs.<property-name>.value]"
Note: You cannot use the reference function in the outputs section of a nested template. To return the values for a deployed resource in a nested template, convert your nested template to a linked template.
If Powershell command is possible, we could get the following command
$deploy = New-AzureRmResourceGroupDeployment -Name $deployment -ResourceGroupName $resourceGroupName -TemplateFile $deployJsonFilePath -TemplateParameterFile $deployJsonParameterFilePath
$outPuts = $deploy.Outputs

Powershell multithreading

I have a Powershell script that converts Office documents to PDF. I would like to multithread it, but cannot figure out how based on other examples I have seen. The main script (OfficeToPDF.ps1) scans through a list of files and calls separate scripts for each file type/office application (ex. for .doc files WordToPDF.ps1 is called to convert). The main script passes 1 file name at a time to the child script ( I did this for a couple of reasons).
Here is an example of the main script:
$documents_path = "C:\Documents\Test_Docs"
$pdf_out_path = "C:\Documents\Converted_PDFs"
$failed_path = "C:\Documents\Failed_to_Convert"
# Sets the root directory of this script
$PSScriptRoot = Split-Path -parent $MyInvocation.MyCommand.Definition
$date = Get-Date -Format "MM_dd_yyyy"
$Logfile = "$PSScriptRoot\logs\OfficeToTiff_$Date.log"
$word2PDF = "$PSScriptRoot\WordToPDF.ps1"
$arguments = "'$documents_path'", "'$pdf_out_path'", "'$Logfile'"
# Function to write to log file
Function LogWrite
{
Param ([string]$logstring)
$time = Get-Date -Format "hh:mm:ss:fff"
Add-content $Logfile -value "$date $time $logstring"
}
################################################################################
# Word to PDF #
################################################################################
LogWrite "*** BEGIN CONVERSION FROM DOC, DOCX, RTF, TXT, HTM, HTML TO PDF ***"
Get-ChildItem -Path $documents_path\* -Include *.docx, *.doc, *.rtf, *.txt, *.htm? -recurse | ForEach-Object {
$original_document = "$($_.FullName)"
# Verifies that a document exists before calling the convert script
If ($original_document -ne $null)
{
Invoke-Expression "$word2PDF $arguments"
#checks to see if document was successfully converted and deleted. If not, doc is moved to another directory
If(Test-Path -path $original_document)
{
Move-Item $original_document $failed_path
}
}
}
$original_document = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
Here is the script (WordToPDF.ps1) that is called by the main script:
Param($documents, $pdf_out_path, $Logfile)
# Function to write to the log file
Function LogWrite
{
Param ([string]$logstring)
$time = Get-Date -Format "hh:mm:ss:fff"
Add-content $Logfile -value "$date $time $logstring"
}
$word_app = New-Object -ComObject Word.Application
$document = $word_app.Documents.Open($_.FullName)
$original_document = "$($_.FullName)"
# Creates the output file name with path
$pdf_document = "$($pdf_out_path)\$($_.BaseName).pdf"
LogWrite "Converting: $original_document to $pdf_document"
$document.SaveAs([ref] $pdf_document, [ref] 17)
$document.Close()
# Deletes the original document after it has been converted
Remove-Item $original_document
LogWrite "Deleting: $original_document"
$word_app.Quit()
Any suggestions would be appreciated.
Thanks.
I was just going to comment and link you to this question: Can PowerShell run commands in Parallel. I then noted the date of that question and the answers, and with PowerShell v3.0 there are some new features that might work better for you.
The question goes over use of the PowerShell jobs. Which can work but require you to keep up with the job status, so can add a bit extra coding to manage.
PowerShell v3 opened up the door a bit more with workflow which is based on Windows Workflow Foundation. A good article on the basics of how this new command works can be found on Script Guy's blog here. You can basically adjust your code to run your conversion via workflow and it will perform this in parallel:
workflow foreachfile {
foreach -parallel ($f in $files) {
#Put your code here that does the work
}
}
Which from what I can find the thread limit this has is 5 threads at a time. I am not sure how accurate that is but blog post here noted the limitation. However, being that the Application com objects for Word and Excel can be very CPU intensive doing 5 threads at a time would probably work well.
I have a multithreaded powershell environment for indicator of compromise scanning on all AD devices- threaded 625 times with Gearman. http://gearman.org
It is open source and allows for an option to go cross platform. It threads with a server worker flow and runs via Python. Extremely recommended by yours truly- someone that has abused threading in powershell. This isn't so much an answer but something that I had never heard of but love and use daily. Pass it forward. Open source for the win :)
I have also used psjobs before and they are great until a certain point of magnitude. Maybe it is my lack of .net expertise but ps has some querky subtle memory nuances that in a large scale can create some nasty effects.

Resources