Update Storage Account
非同步作業會更新標籤、 描述和啟用或停用指定的儲存體帳戶的地理複寫狀態。
要求
Update Storage Account
要求可能會以下面方式指定。 取代 <subscription-id>
與您的訂閱 ID 和 <service-name>
的儲存體帳戶名稱。
方法 | 要求 URI |
---|---|
PUT | https://management.core.windows.net/<subscription-id>/services/storageservices/<service-name> |
您必須確定對管理服務發出的要求是安全的。 如需詳細資訊,請參閱 驗證服務管理要求。
URI 參數
無。
要求標頭
下表描述要求標頭。
要求標頭 | 說明 |
---|---|
Content-Type |
必要項。 此標頭設定為 application/xml 。 |
x-ms-version |
必要項。 指定用於這個要求的作業版本。 此標頭的值必須設定為 2011年-06-01 或更高版本。 版本至少必須是 "2012-03-01" 才能使用地理複寫功能。版本至少必須是 "2013-06-01" 才能使用自訂網域功能。 版本至少必須是 “2013-11-01” 才能使用 SecondaryReadEnabled 功能。 版本應該至少"2014年-06-01"使用 AccountType 欄位。 請注意 GeoReplicationEnabled 和 SecondaryReadEnabled 已不再支援移動向前 – 其功能納入 AccountType 。如需有關版本設定標頭的詳細資訊,請參閱 服務管理版本控制。 |
要求本文
要求主體的格式如下:
<?xml version="1.0" encoding="utf-8"?> <UpdateStorageServiceInput xmlns="https://schemas.microsoft.com/windowsazure"> <Description>description-of-storage-account</Description> <Label>base64-encoded-label</Label> <GeoReplicationEnabled>geo-replication-indicator</GeoReplicationEnabled> <ExtendedProperties> <ExtendedProperty> <Name>property-name</Name> <Value>property-value</Value> </ExtendedProperty> </ExtendedProperties> <CustomDomains> <CustomDomain> <Name>name-of-custom-domain</Name> <UseSubDomainName>cname-validation-indicator</UseSubDomainName> </CustomDomain> </CustomDomains> <SecondaryReadEnabled>secondary-read-indicator</SecondaryReadEnabled> <AccountType>type-of-storage-account</AccountType> </UpdateStorageServiceInput>
下表說明要求主體的元素。
元素名稱 | 說明 |
Label | 選擇項。 指定 base-64 編碼格式的儲存體帳戶名稱。 標籤的長度最多可以有 100 個字元。 在您進行追蹤時,此標籤可用來識別儲存體帳戶。 您必須指定值其中一個 Label 或 Description , ,或兩者。 |
說明 | 選擇項。 儲存體帳戶的描述。 描述的長度最多可以有 1024 個字元。 您必須指定值其中一個 Label 或 Description , ,或兩者。 |
GeoReplicationEnabled | 選擇項。 啟用或停用指定之儲存體的地理複寫。 如果設定為 true , 、 儲存體帳戶中的資料會複寫跨多個地理位置以便啟用面臨重大服務中斷的恢復功能。 如果設定為 false , 、 已停用地理複寫。 若未在要求主體中包含此元素,則目前的值就會保持不變。 Important: 如果您已啟用地理複寫,可以將此元素設定為 false,藉以選擇停用地理複寫。 停用之後,您的資料就不會再複寫至次要資料中心,而且系統會移除次要位置的任何資料。 在停用之後啟用地理複寫會導致系統向儲存體帳戶收取將目前資料複本複寫至次要資料中心的費用。 當現有的資料複本複寫至次要資料中心之後,更新的地理複寫完全免費。GeoReplicationEnabled 項目才提供使用 2012年-03-01 版或更高版本和取代由 AccountType 元素與 2014年-06-01 版或更高版本。 |
ExtendedProperties | 指定已加入至儲存體帳戶之擴充屬性的名稱和值。 |
CustomDomains | 指定與儲存體帳戶相關聯的自訂網域。 CustomDomains 項目只是使用 2013年-06-01 版或更高版本。 |
SecondaryReadEnabled | 指出儲存體帳戶已啟用次要讀取。 可能的值為: - true - false SecondaryReadEnabled 項目只有使用 2013年-11-01 版或更高且取代由 AccountType 元素與 2014年-06-01 版或更高版本。 |
AccountType | 指定帳戶是否支援本機備援儲存體、地理備援儲存體或讀取權限地理備援儲存體。 當您更新儲存體帳戶時,區域備份儲存體不是合適的選項。 可能的值為: - Standard_LRS - Standard_GRS - Standard_RAGRS AccountType 項目只是使用 2014年-06-01 版或更高版本,並取代 SecondaryReadEnabled 和 GeoReplicationEnabled 元素。 Note: Standard_ZRS 和 Premium_LRS 帳戶類型不是選項因為這些帳戶不能變更為其他任何帳戶類型。 此外,所有其他帳戶類型不能變更為 Standard_ZRS 或 Premium_LRS 。 |
ExtendedProperties
指定已加入至儲存體帳戶之擴充屬性的名稱和值。
元素名稱 | 說明 |
---|---|
名稱 | 選擇項。 代表擴充儲存體帳戶屬性的名稱。 每個擴充屬性都必須具有已定義的名稱和值。 您最多可以擁有 50 個擴充屬性名稱/值組。 Name 元素的長度上限為 64 個字元、只有英數字元和底線可用於 Name,而且名稱必須以字母當做開頭。 如果您嘗試使用其他字元、以非字母字元當做 Name 的開頭,或者輸入的名稱與相同儲存體帳戶所擁有之其他擴充屬性的名稱完全相同,就會產生狀態碼 400 (不正確的要求) 錯誤。 Name 項目只是使用 2012年-03-01 版或更高版本。 |
值 | 選擇項。 代表擴充儲存體帳戶屬性的值。 每個擴充屬性都必須具有已定義的名稱和值。 您最多可以擁有 50 個擴充屬性名稱/值組,而且每個擴充屬性值的長度上限為 255 個字元。Value 項目只是使用 2012年-03-01 版或更高版本。 |
CustomDomains
指定與儲存體帳戶相關聯的自訂網域。
元素名稱 | 說明 |
---|---|
CustomDomain | 指定與儲存體帳戶相關聯之自訂網域的相關資訊。 |
名稱 | 指定自訂網域的名稱。 |
UseSubDomainName | 指出是否啟用 CName 驗證。 可能的值為: - true - false |
回應
回應包括 HTTP 狀態碼、一組回應標頭和回應主體。
狀態碼
成功的作業會傳回狀態碼 200 (OK)。 如需狀態碼的相關資訊,請參閱 服務管理狀態和錯誤碼。
回應標頭
這項作業的回應包括下列標頭。 回應也可能包括其他標準 HTTP 標頭。 所有標準標頭符合 HTTP/1.1 通訊協定規格。
回應標頭 | 說明 |
---|---|
x-ms-request-id |
唯一識別對管理服務發出之要求的值。 您可以呼叫非同步作業, 取得作業狀態 以判斷作業已完成之標頭的值、 失敗,還是仍在進行中。 |
回應主體
無。
備註
使用 Update Storage Account
作業可以變更儲存體帳戶的描述、 標籤或地理複寫設定值。 您可以使用 取得儲存體帳戶屬性 作業來檢閱這些值。
範例
下列範例會呼叫 取得儲存體帳戶屬性 來列出儲存體帳戶的初始屬性值的作業會更新 Label
和 Description
屬性呼叫 Update Storage Account
作業接著會顯示更新的結果與另一個呼叫 取得儲存體帳戶屬性。 值變更 Version
所需的版本字串 Thumbprint
到您的管理憑證的憑證指紋值 SubscriptionId
到您的訂閱識別碼和 ServiceName
值來執行範例的儲存體帳戶的名稱。
namespace Microsoft.WindowsAzure.ServiceManagementRESTAPI.Samples { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Xml; using System.Xml.Linq; public class Program { // Set these constants with your values to run the sample. private const string Version = "2011-12-01"; private const string Thumbprint = "management-certificate-thumbprint"; private const string SubscriptionId = "subscription-identifier"; private const string ServiceName = "storage-account-name"; // This is the common namespace for all Service Management REST API XML data. private static XNamespace wa = "https://schemas.microsoft.com/windowsazure"; /// <summary> /// Gets or sets the certificate that matches the Thumbprint value. /// </summary> private static X509Certificate2 Certificate { get; set; } static void Main(string[] args) { try { Certificate = GetStoreCertificate(Thumbprint); // Get the initial property values for the storage account. // Convert the Label property to a readable value for display. XElement initialProperties = GetStorageAccountProperties(ServiceName); XElement labelElement = initialProperties.Descendants(wa + "Label").First(); labelElement.Value = labelElement.Value.FromBase64(); Console.WriteLine( "Storage Account Properties for {0}:{1}{2}", ServiceName, Environment.NewLine, initialProperties.ToString(SaveOptions.OmitDuplicateNamespaces)); // Update the label and description of the storage account. string label = String.Format("updated_{0}_label", ServiceName); string description = String.Format( "Updated description for {0}", ServiceName); UpdateStorageAccount(ServiceName, label, description, geoReplicationEnabled: false); // Get the updated property values for the storage account. // Convert the Label property to a readable value for display. XElement updatedProperties = GetStorageAccountProperties(ServiceName); labelElement = updatedProperties.Descendants(wa + "Label").First(); labelElement.Value = labelElement.Value.FromBase64(); Console.WriteLine( "Updated Storage Account Properties for {0}:{1}{2}", ServiceName, Environment.NewLine, updatedProperties.ToString(SaveOptions.OmitDuplicateNamespaces)); } catch (Exception ex) { Console.WriteLine("Exception caught in Main:"); Console.WriteLine(ex.Message); } Console.Write("Press any key to continue:"); Console.ReadKey(); } /// <summary> /// Calls the Get Storage Account Properties operation in the Service /// Management REST API for the specified subscription and storage account /// name and returns the StorageService XML element from the response. /// </summary> /// <param name="serviceName">The name of the storage account.</param> /// <returns>The StorageService XML element from the response.</returns> private static XElement GetStorageAccountProperties( string serviceName) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, serviceName)); XDocument responseBody; InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody); return responseBody.Element(wa + "StorageService"); } /// <summary> /// Calls the Update Storage Account operation in the Service Management /// REST API for the specified subscription, storage account name, new /// description, label, and geo-replication enabled setting. /// </summary> /// <param name="serviceName">The name of the storage account to update.</param> /// <param name="label">The new label for the storage account.</param> /// <param name="description">The new description for the storage account.</param> /// <param name="geoReplicationEnabled">The new geo-replication setting, if applicable. /// This optional parameter defaults to null.</param> private static void UpdateStorageAccount( string serviceName, string label, string description, bool? geoReplicationEnabled = null) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, serviceName)); XDocument requestBody = new XDocument( new XDeclaration("1.0", "UTF-8", "no"), new XElement( wa + "UpdateStorageServiceInput", new XElement(wa + "Description", description), new XElement(wa + "Label", label.ToBase64()))); // Add the GeoReplicationEnabled element if the version supports it. if ((geoReplicationEnabled != null) && (String.CompareOrdinal(Version, "2011-12-01") >= 0)) { requestBody.Element(wa + "UpdateStorageServiceInput").Add( new XElement( wa + "GeoReplicationEnabled", geoReplicationEnabled.ToString().ToLowerInvariant())); } XDocument responseBody; InvokeRequest(uri, "PUT", HttpStatusCode.OK, requestBody, out responseBody); } /// <summary> /// Gets the certificate matching the thumbprint from the local store. /// Throws an ArgumentException if a matching certificate is not found. /// </summary> /// <param name="thumbprint">The thumbprint of the certificate to find.</param> /// <returns>The certificate with the specified thumbprint.</returns> private static X509Certificate2 GetStoreCertificate(string thumbprint) { List<StoreLocation> locations = new List<StoreLocation> { StoreLocation.CurrentUser, StoreLocation.LocalMachine }; foreach (var location in locations) { X509Store store = new X509Store("My", location); try { store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection certificates = store.Certificates.Find( X509FindType.FindByThumbprint, thumbprint, false); if (certificates.Count == 1) { return certificates[0]; } } finally { store.Close(); } } throw new ArgumentException(string.Format( "A Certificate with Thumbprint '{0}' could not be located.", thumbprint)); } /// <summary> /// A helper function to invoke a Service Management REST API operation. /// Throws an ApplicationException on unexpected status code results. /// </summary> /// <param name="uri">The URI of the operation to invoke using a web request.</param> /// <param name="method">The method of the web request, GET, PUT, POST, or DELETE.</param> /// <param name="expectedCode">The expected status code.</param> /// <param name="requestBody">The XML body to send with the web request. Use null to send no request body.</param> /// <param name="responseBody">The XML body returned by the request, if any.</param> /// <returns>The requestId returned by the operation.</returns> private static string InvokeRequest( Uri uri, string method, HttpStatusCode expectedCode, XDocument requestBody, out XDocument responseBody) { responseBody = null; string requestId = String.Empty; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri); request.Method = method; request.Headers.Add("x-ms-Version", Version); request.ClientCertificates.Add(Certificate); request.ContentType = "application/xml"; if (requestBody != null) { using (Stream requestStream = request.GetRequestStream()) { using (StreamWriter streamWriter = new StreamWriter( requestStream, System.Text.UTF8Encoding.UTF8)) { requestBody.Save(streamWriter, SaveOptions.DisableFormatting); } } } HttpWebResponse response; HttpStatusCode statusCode = HttpStatusCode.Unused; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { // GetResponse throws a WebException for 4XX and 5XX status codes response = (HttpWebResponse)ex.Response; } try { statusCode = response.StatusCode; if (response.ContentLength > 0) { using (XmlReader reader = XmlReader.Create(response.GetResponseStream())) { responseBody = XDocument.Load(reader); } } if (response.Headers != null) { requestId = response.Headers["x-ms-request-id"]; } } finally { response.Close(); } if (!statusCode.Equals(expectedCode)) { throw new ApplicationException(string.Format( "Call to {0} returned an error:{1}Status Code: {2} ({3}):{1}{4}", uri.ToString(), Environment.NewLine, (int)statusCode, statusCode, responseBody.ToString(SaveOptions.OmitDuplicateNamespaces))); } return requestId; } } /// <summary> /// Helpful extension methods for converting strings to and from Base-64. /// </summary> public static class StringExtensions { /// <summary> /// Converts a UTF-8 string to a Base-64 version of the string. /// </summary> /// <param name="s">The string to convert to Base-64.</param> /// <returns>The Base-64 converted string.</returns> public static string ToBase64(this string s) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s); return Convert.ToBase64String(bytes); } /// <summary> /// Converts a Base-64 encoded string to UTF-8. /// </summary> /// <param name="s">The string to convert from Base-64.</param> /// <returns>The converted UTF-8 string.</returns> public static string FromBase64(this string s) { byte[] bytes = Convert.FromBase64String(s); return System.Text.Encoding.UTF8.GetString(bytes); } } }
執行時,範例程式將會產生類似下列範例的輸出:
Storage Account Properties for myexamplestorage1: <StorageService xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Url>https://management.core.windows.net/01234567-89ab-cdef-0123-456789abcdef/services/storageservices/myexamplestorage1</Url> <ServiceName>myexamplestorage1</ServiceName> <StorageServiceProperties> <Description>myexamplestorage1 description</Description> <Location>North Central US</Location> <Label>My Example Label</Label> <Status>Created</Status> <Endpoints> <Endpoint>http://myexamplestorage1.blob.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.queue.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.table.core.windows.net/</Endpoint> </Endpoints> <GeoReplicationEnabled>true</GeoReplicationEnabled> <GeoPrimaryRegion>usnorth</GeoPrimaryRegion> <StatusOfPrimary>Available</StatusOfPrimary> <GeoSecondaryRegion>ussouth</GeoSecondaryRegion> <StatusOfSecondary>Available</StatusOfSecondary> </StorageServiceProperties> </StorageService> Updated Storage Account Properties for myexamplestorage1: <StorageService xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Url>https://management.core.windows.net/01234567-89ab-cdef-0123-456789abcdef/services/storageservices/myexamplestorage1</Url> <ServiceName>myexamplestorage1</ServiceName> <StorageServiceProperties> <Description>Updated description for myexamplestorage1</Description> <Location>North Central US</Location> <Label>updated_myexamplestorage1_label</Label> <Status>Created</Status> <Endpoints> <Endpoint>http://myexamplestorage1.blob.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.queue.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.table.core.windows.net/</Endpoint> </Endpoints> <GeoReplicationEnabled>false</GeoReplicationEnabled> </StorageServiceProperties> </StorageService> Press any key to continue: