How to convert JSON file content into Powershell object in Powershell runbook? - azure

I'm trying to convert JSON file which is present in storage account data into Powershell object. But I'm not getting the proper output. Output does not contain proper values.
My code:
$storageAccountKey = "xxxx"
$Context = New-AzStorageContext -StorageAccountName 'xxxx' -StorageAccountKey $storageAccountKey
$b='C:\Temp\Scheduled.json'
Get-AzureStorageFileContent -Path $b -ShareName "file-share-name"
$newScheduledRules = Get-Content -Raw $b | ConvertFrom-Json
Write-Output ("########newScheduledRules::###########" + $newScheduledRules)
Output:
Could not get the storage context. Please pass in a storage context or set the current storage context.
########newScheduledRules::############{Scheduled=System.Object[]; Fusion=System.Object[]; MLBehaviorAnalytics=System.Object[]; MicrosoftSecurityIncidentCreation=System.Object[]}

I have reproduced in my environment and got expected results as below and followed below process and followed Microsoft-Document:
Scheduled.json:
{
"Rithwik":"Hello",
"Chotu":"Bojja"
}
Firstly, I have created Storage account and then added a Scheduled.json in file share as below:
Now i have created a runbook and excuted below script in runbook as below:
$storageAccountKey = "PFHxFbVmAEvwBM6/9kW4nORJYA+AStA2QQ1A=="
$Context = New-AzStorageContext -StorageAccountName 'rithwik' -StorageAccountKey $storageAccountKey
$out = "$($env:TEMP)\$([guid]::NewGuid())"
New-Item -Path $out -ItemType Directory -Force
Get-AzStorageFileContent -ShareName "rithwik" -Context $Context -Path 'Scheduled.json' -Destination $out -Force
$newScheduledRules = Get-Content -Path "$out\Scheduled.json" -Raw | ConvertFrom-Json
Write-Output ("########newScheduledRules::###########" + $newScheduledRules)
Output:
Here $out is the Destination Variable.
-Path should be Only the file name Scheduled.json in
Get-AzStorageFileContent command.

It seems the Get-AzureStorageFileContent is missing -Context parameter. It should be something like this
$OutPath = "$($env:TEMP)\$([guid]::NewGuid())"
New-Item -Path $OutPath -ItemType Directory -Force
$storageContext = (Get-AzStorageAccount -ResourceGroupName xxxx -Name xxxx).Context
Get-AzStorageFileContent -ShareName "file-share-name" -Context $storageContext -Path 'Scheduled.json' -Destination $OutPath -Force
$newScheduledRules = Get-Content -Path "$OutPath\Scheduled.json" -Raw | ConvertFrom-Json
Write-Output ("########newScheduledRules::###########" + $newScheduledRules)

Related

Powershell script to download file with current date as filename from Azure blob - Download log file and Remove the Downloaded content from blob

I have PowerShell script which downloads the file with current date as filename from Azure blob. But How to get the log file of the process and how to remove the file which is downloaded from Azure blob through script. Could someone help me in this, Please.
Example.
app_09102021.txt
app_10102021.txt
app_11102021.txt
Below is the script.
$container_name = '$XXX'
$destination_path = 'D:\test'
$Ctx = New-AzStorageContext $ZZZZ -StorageAccountKey $CCVCVCVCV
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$Listblobs = 'app_{0:ddMMyyyy}.txt' -f (Get-Date)
# Just download that blob
Get-AzStorageBlobContent -Context $Ctx -Container $container_name -Blob $Listblobs -Destination $destination_path
I have tested in my environment to download the blobs and delete by using below cmd and its successfully downloaded and got removed from Azure as well .
$container_name = 'testaj'
$destination_path = 'C:\Users\Desktop\test'
$Ctx = New-AzStorageContext 'accountname' -StorageAccountKey 'accountkeyrA=='
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$Listblobs ='app_{0:ddMMyyyy}.txt' -f (Get-Date)
$blob = Get-AzStorageBlobContent -Context $Ctx -Container $container_name -Blob $Listblobs -Destination $destination_path -ErrorAction SilentlyContinue
if($blob -ne $Null)
{
Write-Host ("The File $Listblobs has been downloaded to $destination_path")
Write-Host ("Proceeding to delete the downloaded file from $container_name in Azure!!!")
Remove-AzStorageBlob -Container $container_name -Blob $Listblobs -Context $Ctx
Write-Host ("deleted file from $Listblobs in Azure!!!")
}
else{
write-Host ("The file does not exit")
}
Here is the Output for downloaded and deleted file from blob:
If the file got deleted then it will be something like below:
For more information please refer this MS DOC: Monitoring Azure Blob Storage
UPDATE:
I am looking for the solution to search & match the date with today's
date in filename, not sorting by last modified date/time.
Tried with the below code to download all the blobs with todays date for e.g abc_04012022,app_04012022 and delete them from Azure
PS Script :-
$container_name = 'test'
$destination_path = 'C:\Users\Desktop\test'
$Ctx = New-AzStorageContext 'accountname' -StorageAccountKey 'accountkey=='
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$latestBlob = Get-Date -UFormat '%d%m%Y'
$bloblist = Get-AzStorageBlob -Container $container_name -Context $Ctx |select -Property Name
foreach($item in $bloblist){
if($item.Name -match $latestBlob){
Write-Output "Here is the blobs"
$blob = Get-AzStorageBlobContent -Context $Ctx -Container $container_name -Blob $item.Name -Destination $destination_path -ErrorAction SilentlyContinue
if($blob -ne $Null)
{
Write-Output ("The File $item.Name has been downloaded to $destination_path")
Write-Output ("Proceeding to delete the downloaded file from $container_name in Azure!!!")
Remove-AzStorageBlob -Container $container_name -Blob $item.Name -Context $Ctx
Write-Output ("deleted file from $item.Name in Azure!!!")
}
else{
write-Output ("The file does not exit")
}
}
}
Screenshot for reference:

Argument not serializable PowerShell

I have a strange error, I'm running a PowerShell script in DevOps and at the end I want the contents sent to a storage account, I use the snippet below, which works in PowerShell ISE
$strgrg = "storage-rg"
$StorageAccountName = "storageaccount2021"
$ContainerName = "container1"
$Filename = "nsg.txt"
$endtime = (get-date).AddHours("2")
$ctx = (Get-AzStorageAccount -ResourceGroupName $strgrg -Name $StorageAccountName).context
$StorageAccountKey = New-AzStorageContainerSASToken -Context $ctx -Name $ContainerName -Permission racwdl -ExpiryTime $endtime
Set-AzStorageBlobContent -file ./$Filename -Container $ContainerName -Blob $Filename -Context $ctx -force
The error I get is:
WARNING: System.ArgumentException: Argument passed in is not serializable.
Parameter name: value at System.Collections.ListDictionaryInternal.set_Item(Object key, Object value)
at Microsoft.WindowsAzure.Commands.Common.MetricHelper.PopulatePropertiesFromQos(AzurePSQoSEvent qos, IDictionary`2 eventProperties, Boolean populateException)
at Microsoft.WindowsAzure.Commands.Common.MetricHelper.LogUsageEvent(AzurePSQoSEvent qos)
I put some debugging in and it looks like the error occurs after $endtime = (get-date).AddHours("2") when it's running the following line, but that seems fine $ctx = (Get-AzStorageAccount -ResourceGroupName $strgrg -Name $StorageAccountName).context
Can anyone see where I've gone wrong?
Thanks in advance :)

Unable to connect to storage account from Azure functions. Need to store the file in storage account through Azure functions

Requirement is to store the file in storage account through Azure Functions in PowerShell.
Below is the code
$todaydate = Get-Date -Format MM-dd-yy
$LogFull = "AzureScan-$todaydate.log"
$LogItem = New-Item -ItemType File -Name $LogFull
" Text to write" | Out-File -FilePath $LogFull -Append
#Get key to storage account
$acctKey = (Get-AzureRmStorageAccountKey -Name amsaccount1 -
ResourceGroupName RGAMS).Value[0]
#Map to the reports BLOB context
$storageContext = New-AzureStorageContext -StorageAccountName
"amsaccount1" -StorageAccountKey $acctKey
#Copy the file to the storage account
Set-AzureStorageBlobContent -File $LogFull -Container "files" -BlobType
"Block" -Context $storageContext -Verbose

Escaping characters on AzureBlobContent

I have got a problem to set my content in AzureBlobStorage.
In local, I have succeeded to replace characters for each files in a directory.
$sourceFolder = "C:\MyDirectory"
$targetFolder = "C:\MyDirectoryEncodeded"
$fileList = Dir $sourceFolder -Filter *.dat
MkDir $targetFolder -ErrorAction Ignore
ForEach($file in $fileList) {
$file | Get-Content | %{$_ -replace '"',''} | %{$_ -replace ',','.'} | Set-Content -Path "tempDirectory\$file"
$newFile = Get-Content "tempDirectory\$file"
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines("targetDirectory\$file" , $newFile,$Utf8NoBomEncoding)
}
exit
But now, I need to do the same in Microsoft Azure.
I get the content into an Azure Blob Storage, I escape characters, I encoding my file in UTF-8NoBom and then I set the encode file into a new Blob Directory.
Nevertheless, I faced an issue when I want to set the new content with escape characters (First line in my loop).
$storageContext = New-AzureStorageContext -ConnectionString "DefaultEndpointsProtocol=https;AccountName=<myAccountName>;AccountKey=<myAccountKey>;"
$sourceFolder = Get-AzureStorageBlob -Container "datablobnotencoded" -Blob "*.dat" -Context $storageContext
$targetFolder = Get-AzureStorageBlob -Container "datablob" -Context $storageContext
MkDir $targetFolder -ErrorAction Ignore
ForEach($file in $sourceFolder) {
Get-AzureStorageBlob -Container "datablobnotencoded" -Blob $file.Name -Context $storageContext | Get-AzureStorageBlobContent | %{$_ -replace '"',''} | %{$_ -replace ',','.'} | Set-AzureStorageBlobContent -File $file.Name -Context $storageContext -CloudBlob $file
$newFile = Get-AzureStorageFileContent -Path $file
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($file , $newFile, $Utf8NoBomEncoding)
}
I've got this error:
Set-AzureStorageBlobContent : Cannot bind parameter 'CloudBlob'.
Cannot convert the
"Microsoft.WindowsAzure.Commands.Storage.Model.ResourceModel.AzureStorageBlob"
value of type
"Microsoft.WindowsAzure.Commands.Storage.Model.ResourceModel.AzureStorageBlob"
to type "Microsoft.WindowsAzure.Storage.Blob.CloudBlob". At line:7
char:264
+ ... lobContent -File $file.Name -Context $storageContext -CloudBlob $file
+ ~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-AzureStorageBlobContent], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.WindowsAzure.Commands.Storage.Blob.SetAzureBlobContentCommand
Thank you for your answers!
There are some mistakes in your powershell scripts:
1.You may misunderstand the usage of Get-AzureStorageBlobContent, it's used to download blob to local, you cann't get the content of the blob, more details refer here.
2.In the loop, you used $newFile = Get-AzureStorageFileContent -Path $file, the Get-AzureStorageFileContent cmdlet is for file share storage, not for the blob storage.
You can use Get-AzureStorageBlobContent to download the blobs to a local folder, then operate on the local file which is downloaded from blob storage. After the file is modified, you can use Set-AzureStorageBlobContent to upload the local files to the specified azure blob storage.
Sample code as below, and works fine at my side:
$context = New-AzureStorageContext -ConnectionString "xxxx"
#download the blobs in specified contianers
$sourceFolder_blob = Get-AzureStorageBlob -Container "test-1" -Blob "*.txt" -Context $context
#the target azure container, which you want to upload the modifed blob to
$taget_container="test-2"
#the local path which is used to store the download blobs, and make sure the folders exist before use.
$sourceFolder_local="d:\test\blob1\"
$targetFolder_local="d:\test\blob2\"
foreach($file in $sourceFolder_blob)
{
#download the specified blob to local path
Get-AzureStorageBlobContent -Container "test-1" -Blob $file.name -Destination $sourceFolder_local -Context $context
#get the local file path
$local_file_path=$sourceFolder_local + $file.name
#set content to the file in target local folder
$local_target_file_path = "$targetFolder_local"+$file.name
#since the files are downloaded to local, you can any operation for the local file
Get-Content $local_file_path | %{$_ -replace '-','!'} | %{$_ -replace ',','.'} | Set-Content -Path $local_target_file_path
$newFile = Get-Content -Path $local_target_file_path
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($local_target_file_path , $newFile,$Utf8NoBomEncoding)
#the last step, upload the modified file to another azure container
Set-AzureStorageBlobContent -File $local_target_file_path -Context $context -Container $taget_container
}

Azure PowerShell Download blob contents from container

I'm trying to download sme blob files from an azure storage account.
There are a mix of other containers and blockblobs in the parent container, I need to download just the blockblobs and not the other containers, I can't find a way of seperating them out, also I need to download some blobs from a conatiner within a container.
My code will download all the contents in the parent blob, including all sub containers.
$sub = "MySub"
$staccname = "straccname1234"
$key = "sdcsecurekeythinghere"
$ctx = New-AzureStorageContext -StorageAccountName $staccname `
-StorageAccountKey $key
$cont = "data\download\files.001" ##the container includes other cntainers and subcontainers
$dest = "C:\blb-Downloads"
Select-AzureSubscription -SubscriptionName $sub –Default
Set-AzureSubscription -Currentstaccname $staccname -SubscriptionName $sub
Get-AzureStorageBlob -Container $cont -Context $ctx
$blobs = Get-AzureStorageBlob -Container $cont -Context $ctx
$blobs | Get-AzureStorageBlobContent –Destination $dest -Context $ctx
There are approx 75 files in the parent blob and 123 files in data\downloads.
Using the newer Azure PowerShell Az module, you can use Get-AzStorageBlob to list all the block blobs from the container, then use Get-AzStorageBlobContent to download the blobs.
As already shown by #George Wallace, we can use Where-Object or its alias ? to filter block blob types.
Demo:
$resourceGroup = "myResourceGroup"
$storageAccount = "myStorageAccount"
$container = "myContainerName"
$destination = "./blobs"
# Create destination directory if it doesn't exist
if (-not (Test-Path -Path $destination -PathType Container)) {
New-Item -Path $destination -ItemType Directory
}
# Get storage account with container we want to download blobs from
$storageAccount = Get-AzStorageAccount -Name $storageAccount -ResourceGroupName $resourceGroup
# Get all BlockBlobs from container
$blockBlobs = Get-AzStorageBlob -Container $container -Context $storageAccount.Context
| Where-Object {$_.BlobType -eq "BlockBlob"}
# Download each blob from container into destination directory
$blockBlobs | Get-AzStorageBlobContent -Destination $destination -Force
Can you not just run the following and limit it to BlockBlobs only?
Get-AzureStorageBlob -Container $cont -Context $ctx | ? {$_.BlobType -eq "BlockBlob"}
This works for me
$storageaccountname = "jawadtestsaacc"
$sastoken = ""
$ContainerName = "access"
$Ctx = New-AzStorageContext -StorageAccountName $storageaccountname -SasToken $sastoken
Get-AzStorageBlob -Container "$ContainerName" -Blob "Az.json" -Context $Ctx | Get-AzStorageBlobContent
or
Get-AzStorageBlobContent -Container "$ContainerName" -Blob "Az.json" -Context $Ctx

Resources