diff --git a/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj b/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj index 6c0cd0b5de2b..8269f9ae3cc8 100644 --- a/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj +++ b/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/src/Storage/Storage.Management/Az.Storage.psd1 b/src/Storage/Storage.Management/Az.Storage.psd1 index 8ce0893b6bbd..918a632ae7a9 100644 --- a/src/Storage/Storage.Management/Az.Storage.psd1 +++ b/src/Storage/Storage.Management/Az.Storage.psd1 @@ -208,7 +208,9 @@ CmdletsToExport = 'Add-AzRmStorageContainerLegalHold', 'Update-AzStorageBlobServiceProperty', 'Update-AzStorageEncryptionScope', 'Update-AzStorageFileServiceProperty', - 'Update-AzStorageServiceProperty' + 'Update-AzStorageServiceProperty', + 'New-AzStorageFileSymbolicLink', + 'Get-AzStorageFileSymbolicLink' # Variables to export from this module # VariablesToExport = @() diff --git a/src/Storage/Storage.Management/ChangeLog.md b/src/Storage/Storage.Management/ChangeLog.md index 0c727a284b35..722c69de2efd 100644 --- a/src/Storage/Storage.Management/ChangeLog.md +++ b/src/Storage/Storage.Management/ChangeLog.md @@ -23,6 +23,9 @@ - `Set-AzStorageAccount` * Supported Enable Metrics when set object replication policy - `Set-AzStorageObjectReplicationPolicy` +* Supported create and get symbolic link in NFS File Share + - `New-AzStorageFileSymbolicLink` + - `Get-AzStorageFileSymbolicLink` ## Version 9.1.0 * Supported set SasExpirationAction as Log or Block, together with SasExpirationPeriod diff --git a/src/Storage/Storage.Management/help/Az.Storage.md b/src/Storage/Storage.Management/help/Az.Storage.md index 21644d81f874..e5b40313664f 100644 --- a/src/Storage/Storage.Management/help/Az.Storage.md +++ b/src/Storage/Storage.Management/help/Az.Storage.md @@ -155,6 +155,9 @@ Gets service properties for Azure Storage File services. ### [Get-AzStorageFileServiceUsage](Get-AzStorageFileServiceUsage.md) Gets the usage of file service in storage account including account limits, file share limits and constants used in recommendations and bursting formula. +### [Get-AzStorageFileSymbolicLink](Get-AzStorageFileSymbolicLink.md) +Gets the value of a symbolic link. Only works in NFS file share. + ### [Get-AzStorageLocalUser](Get-AzStorageLocalUser.md) Gets a specified local user or lists all local users in a storage account. @@ -281,6 +284,9 @@ Creates a hard link to a file in same share. Only works in NFS file share. ### [New-AzStorageFileSASToken](New-AzStorageFileSASToken.md) Generates a shared access signature token for a Storage file. +### [New-AzStorageFileSymbolicLink](New-AzStorageFileSymbolicLink.md) +Creates a symbolic link to a specified file. Only works in NFS file share. + ### [New-AzStorageLocalUserPermissionScope](New-AzStorageLocalUserPermissionScope.md) Creates a permission scope object, which can be used in Set-AzStorageLocalUser. diff --git a/src/Storage/Storage.Management/help/Get-AzStorageFileSymbolicLink.md b/src/Storage/Storage.Management/help/Get-AzStorageFileSymbolicLink.md new file mode 100644 index 000000000000..f83990156333 --- /dev/null +++ b/src/Storage/Storage.Management/help/Get-AzStorageFileSymbolicLink.md @@ -0,0 +1,293 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.Storage.dll-Help.xml +Module Name: Az.Storage +online version: https://learn.microsoft.com/powershell/module/az.storage/get-azstoragefilesymboliclink +schema: 2.0.0 +--- + +# Get-AzStorageFileSymbolicLink + +## SYNOPSIS +Gets the properties of a symbolic link. Only works in NFS file share. + +## SYNTAX + +### ShareName (Default) +``` +Get-AzStorageFileSymbolicLink [-ShareName] [-Path] [-Context ] + [-ServerTimeoutPerRequest ] [-ClientTimeoutPerRequest ] + [-DefaultProfile ] [-ConcurrentTaskCount ] [] +``` + +### Share +``` +Get-AzStorageFileSymbolicLink [-ShareClient] [-Path] [-Context ] + [-ServerTimeoutPerRequest ] [-ClientTimeoutPerRequest ] + [-DefaultProfile ] [-ConcurrentTaskCount ] [] +``` + +### Directory +``` +Get-AzStorageFileSymbolicLink [-ShareDirectoryClient] [-Path] + [-Context ] [-ServerTimeoutPerRequest ] [-ClientTimeoutPerRequest ] + [-DefaultProfile ] [-ConcurrentTaskCount ] [] +``` + +## DESCRIPTION +The **Get-AzStorageFileSymbolicLink** cmdlet retrieves the properties and target path of a symbolic link in an Azure File share. This cmdlet only works with NFS file shares. + +## EXAMPLES + +### Example 1: Get symbolic link properties using share name +```powershell +$ctx = New-AzStorageContext -StorageAccountName "myaccount" -EnableFileBackupRequestIntent +$link = Get-AzStorageFileSymbolicLink -ShareName "nfsshare" -Path "linkdir/mylink" -Context $ctx +$link +$link.FileProperties +$link.FileProperties.PosixProperties +$link.ShareFileSymbolicLinkInfo +``` + +```output +AccountName: myaccount, ShareName: nfsshare + +Type Length Name Path +---- ------ ---- ---- +File 0 mylink linkdir/mylink + +LastModified : 9/17/2025 8:36:43 AM +00:00 +Metadata : {} +ContentLength : 13 +ContentType : application/octet-stream +ETag : "0x8DDF5C554DCC708" +ContentHash : +ContentEncoding : +CacheControl : +ContentDisposition : +ContentLanguage : +CopyCompletedOn : 1/1/0001 12:00:00 AM +00:00 +CopyStatusDescription : +CopyId : +CopyProgress : +CopySource : +CopyStatus : Pending +IsServerEncrypted : True +SmbProperties : Azure.Storage.Files.Shares.Models.FileSmbProperties +LeaseDuration : Infinite +LeaseState : Available +LeaseStatus : Unlocked +PosixProperties : Azure.Storage.Files.Shares.Models.FilePosixProperties + + +FileMode : rwxrwxrwx +Owner : 0 +Group : 0 +FileType : SymLink +LinkCount : 1 + + +ETag : "0x8DDF5C554DCC708" +LastModified : 9/17/2025 8:36:43 AM +00:00 +LinkText : app%2Fmain.exe +``` + +This command gets the properties of a symbolic link named "mylink" in the "links" directory of the NFS file share "nfsshare". + +### Example 2: Get multiple symbolic links in a directory +```powershell +$files = Get-AzStorageFile -ShareName "nfsshare" -Path "linkdir" -Context $ctx | Get-AzStorageFile -ExcludeExtendedInfo +$symLinkFiles = $files | Where-Object {$_.FileProperties.PosixProperties.FileType.ToString() -eq "SymLink"} +foreach ($file in $symLinkFiles) { + $symlink = Get-AzStorageFileSymbolicLink -ShareName "nfsshare" -Path "linkdir/$($file.Name)" -Context $ctx + Write-Output "$($file.Name) -> $([System.Web.HttpUtility]::UrlDecode($symlink.ShareFileSymbolicLinkInfo.LinkText))" +} +``` + +This command first lists all files in "linkdir" directory , then filter out all files which are symbolic link, finally gets symbolic link properties for each file. + +### Example 3: Get symbolic link using ShareClient pipeline +```powershell +$ctx = New-AzStorageContext -StorageAccountName "myaccount" -EnableFileBackupRequestIntent +$shareClient = Get-AzStorageShare -Name "nfsshare" -Context $ctx +$link = $shareClient | Get-AzStorageFileSymbolicLink -Path "linkdir/mylink" +``` + +This command gets a symbolic link using a ShareClient object obtained from Get-AzStorageShare, demonstrating the pipeline usage with the Share parameter set. + +### Example 4: Get symbolic link using ShareDirectoryClient pipeline +```powershell +$ctx = New-AzStorageContext -StorageAccountName "myaccount" -EnableFileBackupRequestIntent +$dirClient = Get-AzStorageFile -ShareName "nfsshare" -Path "linkdir" -Context $ctx +$link = $dirClient | Get-AzStorageFileSymbolicLink -Path "mylink" +``` + +This command gets a symbolic link within a specific directory using a ShareDirectoryClient object, demonstrating the pipeline usage with the Directory parameter set. + +## PARAMETERS + +### -ClientTimeoutPerRequest +The client side maximum execution time for each request in seconds. + +```yaml +Type: System.Nullable`1[System.Int32] +Parameter Sets: (All) +Aliases: ClientTimeoutPerRequestInSeconds + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ConcurrentTaskCount +The total amount of concurrent async tasks. +The default value is 10. + +```yaml +Type: System.Nullable`1[System.Int32] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Context +Azure Storage Context Object + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Path +Path of the symbolic link file to retrieve. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ServerTimeoutPerRequest +The server time out for each request in seconds. + +```yaml +Type: System.Nullable`1[System.Int32] +Parameter Sets: (All) +Aliases: ServerTimeoutPerRequestInSeconds + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ShareClient +ShareClient object indicating the share containing the symbolic link. + +```yaml +Type: Azure.Storage.Files.Shares.ShareClient +Parameter Sets: Share +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ShareDirectoryClient +ShareDirectoryClient object indicating the base folder containing the symbolic link. + +```yaml +Type: Azure.Storage.Files.Shares.ShareDirectoryClient +Parameter Sets: Directory +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ShareName +Name of the file share containing the symbolic link. + +```yaml +Type: System.String +Parameter Sets: ShareName +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### Azure.Storage.Files.Shares.ShareClient + +### Azure.Storage.Files.Shares.ShareDirectoryClient + +### System.String + +### Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext + +## OUTPUTS + +### Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel.AzureStorageFile + +## NOTES +- This cmdlet only works with NFS file shares +- The returned object contains the symbolic link properties including the target path (LinkText) +- Use the FileProperties.LinkText property to access the target path of the symbolic link +- The FileProperties.IsSymbolicLink property can be used to verify the file is indeed a symbolic link + +## RELATED LINKS + +[New-AzStorageFileSymbolicLink](./New-AzStorageFileSymbolicLink.md) + +[Get-AzStorageFile](./Get-AzStorageFile.md) + +[New-AzStorageFileHardLink](./New-AzStorageFileHardLink.md) diff --git a/src/Storage/Storage.Management/help/New-AzStorageFileSymbolicLink.md b/src/Storage/Storage.Management/help/New-AzStorageFileSymbolicLink.md new file mode 100644 index 000000000000..a94fbb7464ae --- /dev/null +++ b/src/Storage/Storage.Management/help/New-AzStorageFileSymbolicLink.md @@ -0,0 +1,365 @@ +--- +external help file: Microsoft.Azure.PowerShell.Cmdlets.Storage.dll-Help.xml +Module Name: Az.Storage +online version: https://learn.microsoft.com/powershell/module/az.storage/new-azstoragefilesymboliclink +schema: 2.0.0 +--- + +# New-AzStorageFileSymbolicLink + +## SYNOPSIS +Creates a symbolic link to a specified file. Only works in NFS file share. + +## SYNTAX + +### ShareName (Default) +``` +New-AzStorageFileSymbolicLink [-ShareName] [-Path] [-LinkText] + [-Metadata ] [-FileCreatedOn ] [-FileLastWrittenOn ] + [-Owner ] [-Group ] [-Context ] [-ServerTimeoutPerRequest ] + [-ClientTimeoutPerRequest ] [-DefaultProfile ] [-ConcurrentTaskCount ] + [-WhatIf] [-Confirm] [] +``` + +### Share +``` +New-AzStorageFileSymbolicLink [-ShareClient] [-Path] [-LinkText] + [-Metadata ] [-FileCreatedOn ] [-FileLastWrittenOn ] + [-Owner ] [-Group ] [-Context ] [-ServerTimeoutPerRequest ] + [-ClientTimeoutPerRequest ] [-DefaultProfile ] [-ConcurrentTaskCount ] + [-WhatIf] [-Confirm] [] +``` + +### Directory +``` +New-AzStorageFileSymbolicLink [-ShareDirectoryClient] [-Path] + [-LinkText] [-Metadata ] [-FileCreatedOn ] + [-FileLastWrittenOn ] [-Owner ] [-Group ] [-Context ] + [-ServerTimeoutPerRequest ] [-ClientTimeoutPerRequest ] + [-DefaultProfile ] [-ConcurrentTaskCount ] [-WhatIf] [-Confirm] + [] +``` + +## DESCRIPTION +The **New-AzStorageFileSymbolicLink** cmdlet creates a symbolic link to a file in an Azure File share. This cmdlet only works with NFS file shares. A symbolic link is a file that points to another file or directory. The symbolic link can point to files in the same file share or even outside the file share using relative or absolute paths. + +## EXAMPLES + +### Example 1: Create a symbolic link with all optional parameters +```powershell +$ctx = New-AzStorageContext -StorageAccountName "myaccount" -EnableFileBackupRequestIntent +New-AzStorageFileSymbolicLink -ShareName "nfsshare" -Path "links/testlink" -LinkText "config/app.conf" -Metadata @{ "meta1"="value1";"meta2"="value2"} -FileCreatedOn "2025-09-01T00:00:00Z" -FileLastWrittenOn "2025-09-15T12:00:00Z" -Owner "1000" -Group "1000" -Context $ctx +``` + +This command creates a symbolic link with all available optional parametersThe symbolic link points to a relative path "config/app.conf". + +### Example 2: Create a symbolic link using ShareClient object +```powershell +$ctx = New-AzStorageContext -StorageAccountName "myaccount" -EnableFileBackupRequestIntent +$shareClient = Get-AzStorageShare -Name "nfsshare" -Context $ctx +$shareClient | New-AzStorageFileSymbolicLink -Path "dir1/app-link" -LinkText "config/app.conf" +``` + +This command creates a symbolic link using a ShareClient object obtained from Get-AzStorageShare. + +### Example 3: Create a symbolic link using directory client +```powershell +$ctx = New-AzStorageContext -StorageAccountName "myaccount" -EnableFileBackupRequestIntent +$dirClient = Get-AzStorageFile -ShareName "nfsshare" -Path "testdir" -Context $ctx +$dirClient | New-AzStorageFileSymbolicLink -Path "testlink" -LinkText "app/main.exe" +``` + +This command creates a symbolic link within a specific directory using a ShareDirectoryClient object. + +## PARAMETERS + +### -ClientTimeoutPerRequest +The client side maximum execution time for each request in seconds. + +```yaml +Type: System.Nullable`1[System.Int32] +Parameter Sets: (All) +Aliases: ClientTimeoutPerRequestInSeconds + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ConcurrentTaskCount +The total amount of concurrent async tasks. +The default value is 10. + +```yaml +Type: System.Nullable`1[System.Int32] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Context +Azure Storage Context Object + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -DefaultProfile +The credentials, account, tenant, and subscription used for communication with Azure. + +```yaml +Type: Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core.IAzureContextContainer +Parameter Sets: (All) +Aliases: AzureRmContext, AzureCredential + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -FileCreatedOn +The creation time of the symbolic link. + +```yaml +Type: System.Nullable`1[System.DateTimeOffset] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -FileLastWrittenOn +The last write time of the symbolic link. + +```yaml +Type: System.Nullable`1[System.DateTimeOffset] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Group +Optional. +The owner group identifier (GID) to be set on the symbolic link. +The default value is 0 (root group). + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -LinkText +The absolute or relative path to the file to be linked to. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Metadata +Optional custom metadata to set for the symbolic link. + +```yaml +Type: System.Collections.Hashtable +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Owner +Optional. +The owner user identifier (UID) to be set on the symbolic link. +The default value is 0 (root). + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Path +Path of the symbolic link to be created. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ServerTimeoutPerRequest +The server time out for each request in seconds. + +```yaml +Type: System.Nullable`1[System.Int32] +Parameter Sets: (All) +Aliases: ServerTimeoutPerRequestInSeconds + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ShareClient +ShareClient object indicated the share where the symbolic link would be created. + +```yaml +Type: Azure.Storage.Files.Shares.ShareClient +Parameter Sets: Share +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ShareDirectoryClient +ShareDirectoryClient object indicated the base folder where the symbolic link would be created. + +```yaml +Type: Azure.Storage.Files.Shares.ShareDirectoryClient +Parameter Sets: Directory +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ShareName +Name of the file share where the symbolic link would be created. + +```yaml +Type: System.String +Parameter Sets: ShareName +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### Azure.Storage.Files.Shares.ShareClient + +### Azure.Storage.Files.Shares.ShareDirectoryClient + +### System.String + +### Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext + +## OUTPUTS + +### Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel.AzureStorageFile + +## NOTES +- This cmdlet only works with NFS file shares +- Symbolic links can point to files within the same share or external locations +- The symbolic link will appear as a regular file in directory listings but contains a reference to the target path + +## RELATED LINKS + +[Get-AzStorageFileSymbolicLink](./Get-AzStorageFileSymbolicLink.md) + +[New-AzStorageFileHardLink](./New-AzStorageFileHardLink.md) + +[Get-AzStorageFile](./Get-AzStorageFile.md) diff --git a/src/Storage/Storage.common/Storage.common.csproj b/src/Storage/Storage.common/Storage.common.csproj index 154304faaee3..4add4bf55085 100644 --- a/src/Storage/Storage.common/Storage.common.csproj +++ b/src/Storage/Storage.common/Storage.common.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/Storage/Storage/Common/AzureStorageFile.cs b/src/Storage/Storage/Common/AzureStorageFile.cs index ed3370944fd9..d6926af1fd75 100644 --- a/src/Storage/Storage/Common/AzureStorageFile.cs +++ b/src/Storage/Storage/Common/AzureStorageFile.cs @@ -73,10 +73,15 @@ public ShareFileClient ShareFileClient public global::Azure.Storage.Files.Shares.Models.ShareFileItem ListFileProperties { get; private set; } /// - /// XSCL Track2 File Hardlink create returned properties + /// XSCL Track2 File Hardlink/SymbolicLink create returned properties /// public global::Azure.Storage.Files.Shares.Models.ShareFileInfo ShareFileInfo { get; private set; } + /// + /// XSCL Track2 File SymbolicLink get returned properties + /// + public global::Azure.Storage.Files.Shares.Models.ShareFileSymbolicLinkInfo ShareFileSymbolicLinkInfo { get; private set; } + private ShareClientOptions shareClientOptions { get; set; } @@ -100,6 +105,26 @@ public AzureStorageFile(ShareFileClient shareFileClient, AzureStorageContext sto shareClientOptions = clientOptions; } + /// + /// Azure storage file constructor from Track2 list file item + /// + /// + /// + /// + /// + public AzureStorageFile(ShareFileClient shareFileClient, AzureStorageContext storageContext, ShareFileSymbolicLinkInfo info, ShareClientOptions clientOptions = null) + { + Name = shareFileClient.Name; + this.privateFileClient = shareFileClient; + if (info != null) + { + ShareFileSymbolicLinkInfo = info; + LastModified = info.LastModified; + } + Context = storageContext; + shareClientOptions = clientOptions; + } + /// /// Azure storage file constructor from Track2 list file item /// diff --git a/src/Storage/Storage/File/Cmdlet/GetAzureStorageFileSymbolicLink.cs b/src/Storage/Storage/File/Cmdlet/GetAzureStorageFileSymbolicLink.cs new file mode 100644 index 000000000000..6aceb7424ec0 --- /dev/null +++ b/src/Storage/Storage/File/Cmdlet/GetAzureStorageFileSymbolicLink.cs @@ -0,0 +1,83 @@ +using global::Azure.Storage.Files.Shares; +using global::Azure.Storage.Files.Shares.Models; +using Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel; +using Microsoft.WindowsAzure.Commands.Storage.Common; +using Microsoft.WindowsAzure.Commands.Storage.Model.ResourceModel; +using System.Globalization; +using System.Management.Automation; + +namespace Microsoft.WindowsAzure.Commands.Storage.File.Cmdlet +{ + [Cmdlet("Get", Azure.Commands.ResourceManager.Common.AzureRMConstants.AzurePrefix + "StorageFileSymbolicLink", DefaultParameterSetName = Constants.ShareNameParameterSetName), OutputType(typeof(ShareFileSymbolicLinkInfo))] + public class GetAzureStorageFileSymbolicLink : AzureStorageFileCmdletBase + { + [Parameter( + Position = 0, + Mandatory = true, + ParameterSetName = Constants.ShareNameParameterSetName, + HelpMessage = "Name of the file share containing the symbolic link.")] + [ValidateNotNullOrEmpty] + public string ShareName { get; set; } + + [Parameter( + Position = 0, + Mandatory = true, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + ParameterSetName = Constants.ShareParameterSetName, + HelpMessage = "ShareClient object indicating the share containing the symbolic link.")] + [ValidateNotNull] + public ShareClient ShareClient { get; set; } + + [Parameter( + Position = 0, + Mandatory = true, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + ParameterSetName = Constants.DirectoryParameterSetName, + HelpMessage = "ShareDirectoryClient object indicating the base folder containing the symbolic link.")] + [ValidateNotNull] + public ShareDirectoryClient ShareDirectoryClient { get; set; } + + [Parameter( + Position = 1, + Mandatory = true, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Path of the symbolic link file to retrieve.")] + [ValidateNotNullOrEmpty] + public string Path { get; set; } + + // Overwrite the useless parameter + public override SwitchParameter DisAllowTrailingDot { get; set; } + + public override void ExecuteCmdlet() + { + ShareDirectoryClient baseDirClient; + switch (this.ParameterSetName) + { + case Constants.DirectoryParameterSetName: + CheckContextForObjectInput((AzureStorageContext)this.Context); + baseDirClient = this.ShareDirectoryClient; + break; + + case Constants.ShareNameParameterSetName: + NamingUtil.ValidateShareName(this.ShareName, false); + ShareServiceClient fileserviceClient = Util.GetTrack2FileServiceClient((AzureStorageContext)this.Context, ClientOptions); + baseDirClient = fileserviceClient.GetShareClient(this.ShareName).GetRootDirectoryClient(); + break; + + case Constants.ShareParameterSetName: + CheckContextForObjectInput((AzureStorageContext)this.Context); + baseDirClient = this.ShareClient.GetRootDirectoryClient(); + break; + + default: + throw new PSArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid parameter set name: {0}", this.ParameterSetName)); + } + ShareFileClient sharefile = baseDirClient.GetFileClient(this.Path); + ShareFileSymbolicLinkInfo info = sharefile.GetSymbolicLink(this.CmdletCancellationToken).Value; + WriteObject(new AzureStorageFile(sharefile, (AzureStorageContext)this.Context, info, this.ClientOptions)); + } + } +} \ No newline at end of file diff --git a/src/Storage/Storage/File/Cmdlet/NewAzureStorageFileSymbolicLink.cs b/src/Storage/Storage/File/Cmdlet/NewAzureStorageFileSymbolicLink.cs new file mode 100644 index 000000000000..f10c9c2ea8de --- /dev/null +++ b/src/Storage/Storage/File/Cmdlet/NewAzureStorageFileSymbolicLink.cs @@ -0,0 +1,144 @@ +using global::Azure.Storage.Files.Shares; +using global::Azure.Storage.Files.Shares.Models; +using Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel; +using Microsoft.WindowsAzure.Commands.Storage.Common; +using Microsoft.WindowsAzure.Commands.Storage.Model.ResourceModel; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Management.Automation; + +namespace Microsoft.WindowsAzure.Commands.Storage.File.Cmdlet +{ + [Cmdlet("New", Azure.Commands.ResourceManager.Common.AzureRMConstants.AzurePrefix + "StorageFileSymbolicLink", DefaultParameterSetName = Constants.ShareNameParameterSetName, SupportsShouldProcess = true), OutputType(typeof(AzureStorageFile))] + public class NewAzureStorageFileSymbolicLink : AzureStorageFileCmdletBase + { + [Parameter( + Position = 0, + Mandatory = true, + ParameterSetName = Constants.ShareNameParameterSetName, + HelpMessage = "Name of the file share where the symbolic link would be created.")] + [ValidateNotNullOrEmpty] + public string ShareName { get; set; } + + [Parameter( + Position = 0, + Mandatory = true, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + ParameterSetName = Constants.ShareParameterSetName, + HelpMessage = "ShareClient object indicated the share where the symbolic link would be created.")] + [ValidateNotNull] + public ShareClient ShareClient { get; set; } + + [Parameter( + Position = 0, + Mandatory = true, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + ParameterSetName = Constants.DirectoryParameterSetName, + HelpMessage = "ShareDirectoryClient object indicated the base folder where the symbolic link would be created.")] + [ValidateNotNull] + public ShareDirectoryClient ShareDirectoryClient { get; set; } + + [Parameter( + Position = 1, + Mandatory = true, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Path of the symbolic link to be created.")] + [ValidateNotNullOrEmpty] + public string Path { get; set; } + + [Parameter( + Position = 2, + Mandatory = true, + HelpMessage = "The absolute or relative path to the file to be linked to.")] + [ValidateNotNullOrEmpty] + public string LinkText { get; set; } + + [Parameter( + Mandatory = false, + HelpMessage = "Optional custom metadata to set for the symbolic link.")] + public Hashtable Metadata { get; set; } + + [Parameter( + Mandatory = false, + HelpMessage = "The creation time of the symbolic link.")] + [ValidateNotNullOrEmpty] + public DateTimeOffset? FileCreatedOn { get; set; } + + [Parameter( + Mandatory = false, + HelpMessage = "The last write time of the symbolic link.")] + [ValidateNotNullOrEmpty] + public DateTimeOffset? FileLastWrittenOn { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Optional. The owner user identifier (UID) to be set on the symbolic link. The default value is 0 (root).")] + [ValidateNotNullOrEmpty] + public string Owner { get; set; } + + [Parameter(Mandatory = false, HelpMessage = "Optional. The owner group identifier (GID) to be set on the symbolic link. The default value is 0 (root group).")] + [ValidateNotNullOrEmpty] + public string Group { get; set; } + + // Overwrite the useless parameter + public override SwitchParameter DisAllowTrailingDot { get; set; } + + public override void ExecuteCmdlet() + { + if (ShouldProcess(this.Path, "Create File Symbolic Link")) + { + ShareDirectoryClient baseDirClient; + switch (this.ParameterSetName) + { + case Constants.DirectoryParameterSetName: + CheckContextForObjectInput((AzureStorageContext)this.Context); + baseDirClient = this.ShareDirectoryClient; + break; + + case Constants.ShareNameParameterSetName: + NamingUtil.ValidateShareName(this.ShareName, false); + ShareServiceClient fileserviceClient = Util.GetTrack2FileServiceClient((AzureStorageContext)this.Context, ClientOptions); + baseDirClient = fileserviceClient.GetShareClient(this.ShareName).GetRootDirectoryClient(); + break; + + case Constants.ShareParameterSetName: + CheckContextForObjectInput((AzureStorageContext)this.Context); + baseDirClient = this.ShareClient.GetRootDirectoryClient(); + break; + + default: + throw new PSArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid parameter set name: {0}", this.ParameterSetName)); + } + ShareFileClient sharefile = baseDirClient.GetFileClient(this.Path); + + // Convert Hashtable to IDictionary + IDictionary metadata = null; + if (this.Metadata != null) + { + metadata = new Dictionary(); + foreach (DictionaryEntry entry in this.Metadata) + { + if (entry.Key != null && entry.Value != null) + { + metadata[entry.Key.ToString()] = entry.Value.ToString(); + } + } + } + + var options = new ShareFileCreateSymbolicLinkOptions + { + Metadata = metadata, + FileCreatedOn = this.FileCreatedOn, + FileLastWrittenOn = this.FileLastWrittenOn, + Owner = this.Owner, + Group = this.Group + }; + ShareFileInfo info = sharefile.CreateSymbolicLink(this.LinkText, options, this.CmdletCancellationToken).Value; + WriteObject(new AzureStorageFile(sharefile, (AzureStorageContext)this.Context, info, this.ClientOptions)); + } + } + } +} \ No newline at end of file diff --git a/src/Storage/Storage/Storage.csproj b/src/Storage/Storage/Storage.csproj index ef7df0c94937..25433d9563af 100644 --- a/src/Storage/Storage/Storage.csproj +++ b/src/Storage/Storage/Storage.csproj @@ -13,10 +13,10 @@ - - - - + + + +