我有一个powershell模块,它试图将blob上传到azure存储。一切都会检出,直到实际上传blob的最后一行。
我收到以下错误:
Exception calling "UploadText" with "1" argument(s):
"The specified resource does not exist."
At line:1 char:1
+ $blob.UploadText("asdasdfsdf")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : StorageClientException
我也试过使用带有3个args的重载,但同样存在同样的问题。
这是模块:
Function Add-BlobText
{
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,Position = 0)]
[string]
$StorageAccount,
[Parameter(Mandatory = $true,Position = 1)]
[string]
$Container,
[Parameter(Mandatory = $true,Position = 2)]
[string]
$BlobName,
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string]
$BlobText
) #end param
Add-Type -Path "C:\Assemblies\Microsoft.WindowsAzure.StorageClient.dll"
Set-AzureSubscription -SubscriptionName "MySubName"
$secondaryKey = (Get-AzureStorageKey -StorageAccountName $storageAccount).Secondary
$creds = New-Object Microsoft.WindowsAzure.StorageCredentialsAccountAndKey($StorageAccount,$secondaryKey)
$cloudStorageAccount = New-Object Microsoft.WindowsAzure.CloudStorageAccount($creds, $true)
[Microsoft.WindowsAzure.StorageClient.CloudBlobClient]$cloudBlobClient = New-Object Microsoft.WindowsAzure.StorageClient.CloudBlobClient($cloudStorageAccount.BlobEndpoint)
[Microsoft.WindowsAzure.StorageClient.CloudBlobContainer]$blobContainer = $cloudBlobClient.GetContainerReference($Container)
[Microsoft.WindowsAzure.StorageClient.CloudBlob]$blob = $blobContainer.GetBlobReference($BlobName)
$blob.UploadText($BlobText)
} #end Function Add-BlobText
我已经能够将其作为二进制模块(下面)。如果有人能够弄清楚为什么UploadText()
在二进制模块中工作但在脚本模块中抛出异常,请告诉我。
[Cmdlet(VerbsCommon.Add, "BlobText")]
public class AddBlobText : PSCmdlet
{
[Parameter(Mandatory = true, Position = 0)]
public string StorageAccount { get; set; }
[Parameter(Mandatory = true, Position = 1)]
public string Container { get; set; }
[Parameter(Mandatory = true, Position = 2)]
public string BlobName { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public string BlobText { get; set; }
protected override void ProcessRecord()
{
PowerShell ps = PowerShell.Create();
ps.AddScript("Set-AzureSubscription -SubscriptionName 'MySubName'");
string keyScript = "( Get-AzureStorageKey -StorageAccountName " + StorageAccount + " ).Secondary";
ps.AddScript(keyScript);
Collection<PSObject> result = ps.Invoke();
string secondaryKey = result[0].ToString();
StorageCredentialsAccountAndKey credentials = new StorageCredentialsAccountAndKey(StorageAccount, secondaryKey);
CloudStorageAccount storageAccount = new CloudStorageAccount(credentials, true);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(Container);
var blob = container.GetBlobReference(BlobName);
blob.UploadText(BlobText);
}
}
答案 0 :(得分:2)
这可能是因为您的容器不存在。初始化容器后,应该调用CreateIfNotExist
以确保它存在:
[Microsoft.WindowsAzure.StorageClient.CloudBlobContainer]$blobContainer = $cloudBlobClient.GetContainerReference($Container)
$blobContainer.CreateIfNotExist() <-- Here
[Microsoft.WindowsAzure.StorageClient.CloudBlob]$blob = $blobContainer.GetBlobReference($BlobName)
$blob.UploadText($BlobText)
答案 1 :(得分:2)
此错误非常模糊且具有误导性,但有些实例“Azure存储可能会”混淆“。看看桑德里诺的例子,特别是这一行,
[Microsoft.WindowsAzure.StorageClient.CloudBlob]$blob = $blobContainer.GetBlobReference($BlobName)
并非Sandrino的答案是您的问题,但是在将一个Url或其他令人困惑的密钥字符串传递给Azure存储容器时会遇到您遇到的异常。
不幸的是,我不是Powershell的人,但这是一个复制示例然后修复C#。
public void Save(string objId, T obj)
{
CloudBlob blob = this.container.GetBlobReference(objId); // Problematic if a URL
blob.Properties.ContentType = "application/json";
var serialized = string.Empty;
serialized = serializer.Serialize(obj);
if (this.jsonpSupport)
{
serialized = this.container.Name + "Callback(" + serialized + ")";
}
blob.UploadText(serialized);
}
假设 this.container 是指向 http://127.0.0.1:10000/devstoreaccount1/sggames 的有效blob存储实例或任何有效容器的实例。
objId 是一个包含 https://www.google.com/accounts/o8/id?id=AItOawk4Dw9sLxSc-zmdWQHdZNcyzkTcvKUkhiE 等网址的密钥......是的,这可能会发生,在我的情况下,这是一个实际的身份声明来自谷歌使用Azure ACS。
在 GetBlobReference 调用之后,blob实例已经损坏,现在看着乱糟糟的Uri - &gt; https://www.google.com/accounts/o8/id?id=AItOawk4Dw9sLxSc-zmdWQHdZNcyzkTcvKUkhiE
不幸的是,简单地调用 $ blobContainer.CreateIfNotExist()的解决方案不是解决方案,也不起作用。包含Uri结构的键将仅用于重新解释blob存储位置。
解决方案(除了daredev的更新)将是这样的:
if (Uri.IsWellFormedUriString(claim, UriKind.Absolute) && HttpUtility.ParseQueryString(claim).Count > 0)
{
claim = HttpUtility.ParseQueryString(claim)[0];
}
在上面的方法中添加此代码以清理任何Uri,但如果您需要维护完整密钥,则可以使用任何适当的方法,如Base64编码URL。
以下是显示我所描述的结果的前后图像。
糟糕:
注意坏URI
这个坏的URI扩大了实际的存储blob位置
这是daredev的相同例外
好处:
新刷新的密钥,请注意它只是URL查询字符串上的值
Azure存储URI现在看起来不错
尤里卡!
希望这有帮助。
答案 2 :(得分:1)
这是我用来将文件上传到Azure Blob的PowerShell脚本:Uploading to Azure Storage
$SubscriptionName = ""
$SubscriptionId = ""
$DestContainer = ""
$StorageAccountName = ""
Import-AzurePublishSettingsFile -PublishSettingsFile "<Location of the publishsettings-file>"
Set-AzureSubscription -SubscriptionId $SubscriptionId -CurrentStorageAccountName $StorageAccountName
Select-AzureSubscription -SubscriptionName $SubscriptionName
Set-AzureStorageBlobContent -File "<File you want to upload>" -Container $DestContainer