VMware Horizon Community
Sravan_k
Expert
Expert
Jump to solution

is there any comment (which can run on end user machine) that shows list of app stacks attached to end user?

Hi Everyone,

How to find out, list of app stacks thous are attached to end user's by ruining commend on end user machine through command prompt (CMD)   

I know we can find it from app volume manager GUI,

but I am looking for a command, which can display list out app stacks attached to end user?

Thanks

Tags (1)
1 Solution

Accepted Solutions
tschuegy
Enthusiast
Enthusiast
Jump to solution

Here are the complete source code for your request: https://1drv.ms/u/s!An1G6213BZX-gRWDaGK9tPJQigdL

In this zip file is the entire visual studio project. I have my project modified for you. It will only display assigned appstacks.

In the folder AppVolumesSelfService\bin\Debug\ is a config file "AppVolumesListAppStacks.exe.config". Please modify that for your environment.

Tschuegy

View solution in original post

25 Replies
Ray_handels
Virtuoso
Virtuoso
Jump to solution

To be hontes I don't think you can. You could use the svservice.exe command located in the Program files CLoudvolumes directory but I can't seem to find a command that cn do this.

Sravan_k
Expert
Expert
Jump to solution

Hi Ray,

Thanks for responding, Yes I can find it (svservice.exe) but can't not able to run as a normal user,

however I can run it as a administrator user, but I can't see any information, what I mean is when I run svservice.exe it just opened a command prompt and closed (it happened with in 20 milliseconds)

can you please help me out at this point?

Ray_handels
Virtuoso
Virtuoso
Jump to solution

I guess the answer to your question is "No it can't". I do understand that it sucks to hear that but I don't think you will see this information using the svservice.

And if you want to know all commands go to the command prompt and to the Appvolumes agent folder and type in svservice.exe /? to see all command line options.

Another trick you might be able to use (I can't help you with this, just bringing up the idea) is to use an AD group to assign the application and write an application using powershelle that checks to see of which of those groups you are a member of. This way you can see which applications are assigned to you.

alsmk2
Hot Shot
Hot Shot
Jump to solution

If you can browse the C:\ drive of the desktop, you can go to c:\snapvolumestemp and drill down into that. You should be able to work out which appstacks are attached by the apps listed in each mount point.

Not ideal, but is helpful if you don't have access to vsphere at the time.

Sravan_k
Expert
Expert
Jump to solution

Thank you Alsmk2 it is helpful at this point, but I can not see the snapvolumestemp folder even I enabled hidden files.

but when I search with  'c:\snapvolumestemp' I founded it, may I know the reason why it is not showing?

Lakshman
Champion
Champion
Jump to solution

"C:\snapvolumestemp" is a hidden folder managed by App Volumes to mount AppStack or writable volumes.

Sravan_k
Expert
Expert
Jump to solution

Hi Lakshman,

Actually, I enabled the hidden files on my system, Thanks for responding 

0 Kudos
Ray_handels
Virtuoso
Virtuoso
Jump to solution

If you go to that directory you can only see how many disks are actualy attached.

Because your Appvolumes Agent is a filter driver it will show all available folders on your machine there, not only the folders you created in the appstack. Hence the reason you need to have a machine with no appvolumes agent installed (or at least stopped) before manually editing the appstack. All appstacks will look exactly the same if you browse them.

alsmk2
Hot Shot
Hot Shot
Jump to solution

When I browse that directory, I can work out quite rapidly what appstack is attached as one of the folders on each mount point contains icons for apps - has served me well for a while :smileysilly:

You shouldn't need to enable hidden folders either - just manually typing it into explorer will get you there.

tschuegy
Enthusiast
Enthusiast
Jump to solution

Another way: I have written a small application in vb.net. It connects with a service account to the REST API of App Volumes Manager and get the info. As en example for you, here are one of my function:

Private Sub GetAttachments()

        Dim requestUri As Uri

        requestUri = New Uri(My.Settings.AVURL + "/cv_api/attachments")

        dgv_Attachments.Rows.Clear()

        dgv_Attachments.Enabled = False

        Try

            Dim httpWebRequest As HttpWebRequest = CType(WebRequest.Create(requestUri), HttpWebRequest)

            httpWebRequest.ContentType = "application/json"

            httpWebRequest.Method = "GET"

            httpWebRequest.CookieContainer = modGlobals.AppVolumes_cookies

            httpWebRequest.ServerCertificateValidationCallback = AddressOf oProgram.AcceptAllCertifications

            Dim responseStream As Stream = httpWebRequest.GetResponse().GetResponseStream()

            Dim streamReader As StreamReader = New StreamReader(responseStream)

            Dim text As String = streamReader.ReadToEnd()

            streamReader.Close()

            Dim javaScriptSerializer As JavaScriptSerializer = New JavaScriptSerializer()

            Dim instance8 As Array = Strings.Split(text, "[", -1, CompareMethod.Binary)

            Dim text6 As String = Conversions.ToString(NewLateBinding.LateIndexGet(instance8, New Object() {1}, Nothing))

            text6 = "[" + text6

            text6 = text6.Remove(text6.Length - 1)

            Dim list5 As List(Of AppVolumes.AppVolumes.Attachments) = CType(javaScriptSerializer.Deserialize(text6, GetType(List(Of AppVolumes.AppVolumes.Attachments))), List(Of AppVolumes.AppVolumes.Attachments))

            If list5.Count = 0 Then

            Else

                Dim arg_800_0 As Integer = 0

                Dim num5 As Integer = list5.Count - 1

                Dim strComputer As String = ""

                For m As Integer = arg_800_0 To num5

                    Dim pattern As String

                    Dim input As String

                    Dim text7 As String = list5(m).snapvol

                    Dim instance9 As Array = Strings.Split(text7, ">", -1, CompareMethod.Binary)

                    Dim instance10 As Array = Strings.Split(Conversions.ToString(NewLateBinding.LateIndexGet(instance9, New Object() {1}, Nothing)), "<", -1, CompareMethod.Binary)

                    text7 = Strings.Replace(Conversions.ToString(NewLateBinding.LateIndexGet(instance10, New Object() {0}, Nothing)), "\\", "\", 1, -1, CompareMethod.Binary)

                    pattern = "title=\""(\w+)\"""

                    input = list5(m).computer

                    For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)

                        strComputer = match.Groups(1).Value

                        Exit For

                    Next

                    If String.IsNullOrEmpty(txtFilter.Text) Then

                        dgv_Attachments.Rows.Add(list5(m).entityt, text7, strComputer, list5(m).mount_type, list5(m).assign_type, list5(m).event_time_human, list5(m).duration)

                    Else

                        If InStr(LCase(text7), LCase(txtFilter.Text)) Or InStr(LCase(strComputer), LCase(txtFilter.Text)) Then

                            dgv_Attachments.Rows.Add(list5(m).entityt, text7, strComputer, list5(m).mount_type, list5(m).assign_type, list5(m).event_time_human, list5(m).duration)

                        End If

                    End If

                Next

            End If

        Catch ex As Exception

        End Try

    End Sub

Sravan_k
Expert
Expert
Jump to solution

Hi tschuegy,

Thanks for sharing it with me, can I use it?

0 Kudos
tschuegy
Enthusiast
Enthusiast
Jump to solution

Hi Sravan,

I cannot give you my entire source code, but you can use my code snipped that i have posted. I can describe how you can use it:

Create form that looks similar to this:

AppVolumesSelfService_Form.PNG

Code for this form:

Imports System.IO

Imports System.Net

Imports System.Web.Script.Serialization

Imports Microsoft.VisualBasic.CompilerServices

Imports System.Text.RegularExpressions

Public Class frmAttachments

    Public oProgram As New AppVolumes_Toolbox.Program

    Private Sub frmAttachments_Shown(sender As Object, e As EventArgs) Handles Me.Shown

        GetAttachments()

        ' Remove DTGView selection

        dgv_Attachments.ClearSelection()

        dgv_Attachments.CurrentCell = Nothing

    End Sub

    Private Sub GetAttachments()

        Dim requestUri As Uri

        requestUri = New Uri(My.Settings.AVURL + "/cv_api/attachments")

        dgv_Attachments.Rows.Clear()

        dgv_Attachments.Enabled = False

        Try

            Dim httpWebRequest As HttpWebRequest = CType(WebRequest.Create(requestUri), HttpWebRequest)

            httpWebRequest.ContentType = "application/json"

            httpWebRequest.Method = "GET"

            httpWebRequest.CookieContainer = modGlobals.AppVolumes_cookies

            httpWebRequest.ServerCertificateValidationCallback = AddressOf oProgram.AcceptAllCertifications

            Dim responseStream As Stream = httpWebRequest.GetResponse().GetResponseStream()

            Dim streamReader As StreamReader = New StreamReader(responseStream)

            Dim text As String = streamReader.ReadToEnd()

            streamReader.Close()

            Dim javaScriptSerializer As JavaScriptSerializer = New JavaScriptSerializer()

            Dim instance8 As Array = Strings.Split(text, "[", -1, CompareMethod.Binary)

            Dim text6 As String = Conversions.ToString(NewLateBinding.LateIndexGet(instance8, New Object() {1}, Nothing))

            text6 = "[" + text6

            text6 = text6.Remove(text6.Length - 1)

            Dim list5 As List(Of AppVolumes_Toolbox.AppVolumes.Attachments) = CType(javaScriptSerializer.Deserialize(text6, GetType(List(Of AppVolumes_Toolbox.AppVolumes.Attachments))), List(Of AppVolumes_Toolbox.AppVolumes.Attachments))

            If list5.Count = 0 Then

            Else

                Dim arg_800_0 As Integer = 0

                Dim num5 As Integer = list5.Count - 1

                Dim strComputer As String = ""

                For m As Integer = arg_800_0 To num5

                    Dim pattern As String

                    Dim input As String

                    Dim text7 As String = list5(m).snapvol

                    Dim instance9 As Array = Strings.Split(text7, ">", -1, CompareMethod.Binary)

                    Dim instance10 As Array = Strings.Split(Conversions.ToString(NewLateBinding.LateIndexGet(instance9, New Object() {1}, Nothing)), "<", -1, CompareMethod.Binary)

                    text7 = Strings.Replace(Conversions.ToString(NewLateBinding.LateIndexGet(instance10, New Object() {0}, Nothing)), "\\", "\", 1, -1, CompareMethod.Binary)

                    pattern = "title=\""(\w+)\"""

                    input = list5(m).computer

                    For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)

                        strComputer = match.Groups(1).Value

                        Exit For

                    Next

                    If String.IsNullOrEmpty(txtFilter.Text) Then

                        dgv_Attachments.Rows.Add(list5(m).entityt, text7, strComputer, list5(m).mount_type, list5(m).assign_type, list5(m).event_time_human, list5(m).duration)

                    Else

                        If InStr(LCase(text7), LCase(txtFilter.Text)) Or InStr(LCase(strComputer), LCase(txtFilter.Text)) Then

                            dgv_Attachments.Rows.Add(list5(m).entityt, text7, strComputer, list5(m).mount_type, list5(m).assign_type, list5(m).event_time_human, list5(m).duration)

                        End If

                    End If

                Next

            End If

        Catch expr_1DB0 As Exception

            Dim ex As Exception = expr_1DB0

            If Strings.InStr(ex.Message, "403", CompareMethod.Binary) <> 0 Then

                If modGlobals.Global_logoff = False Then

                    MsgBox(oProgram.rm.GetString("Session_Expired", oProgram.culture), MsgBoxStyle.OkOnly, Nothing)

                End If

                oProgram.LogMessage(oProgram.rm.GetString("Session_Expired", oProgram.culture))

                frmMain.frmMainShared.ThreadAV()

                Me.Close()

            Else

                If modGlobals.Global_logoff = False Then

                    MsgBox(ex.Message, MsgBoxStyle.OkOnly, Nothing)

                End If

            End If

        Finally

            dgv_Attachments.Enabled = True

        End Try

    End Sub

    Private Sub ToolStripButton1_Click(sender As Object, e As EventArgs) Handles ToolStripButton1.Click

        GetAttachments()

    End Sub

    Private Sub txtFilter_KeyDown(sender As Object, e As KeyEventArgs) Handles txtFilter.KeyDown

        If e.KeyCode = Keys.Enter Then

            e.SuppressKeyPress = True

            GetAttachments()

            ' Remove DTGView selection

            dgv_Attachments.ClearSelection()

            dgv_Attachments.CurrentCell = Nothing

        End If

    End Sub

End Class

You also need a class. I called this class AppVolumes_Toolbox

Imports System.Net

Imports System.Net.Security

Imports System.Runtime.CompilerServices

Imports System.Data.SqlClient

Imports System.Globalization

Imports System.Resources

Imports System.Text

Imports Microsoft.VisualBasic.CompilerServices

Imports System.IO

Imports System.Web.Script.Serialization

Imports System.Security.Cryptography.X509Certificates

Imports System.Web

Imports System.DirectoryServices

Imports System.Management

Imports System.Threading

Namespace AppVolumes_Toolbox

Public Class AppVolumes

Public Class Attachments

            <CompilerGenerated()>

            Private _entityt As String

            <CompilerGenerated()>

            Private _entity As String

            <CompilerGenerated()>

            Private _snapvol As String

            <CompilerGenerated()>

            Private _snapvol_file As AppVolumes.snapvolfile

            <CompilerGenerated()>

            Private _volume_type As String

            <CompilerGenerated()>

            Private _duration As String

            <CompilerGenerated()>

            Private _event_time_human As String

            <CompilerGenerated()>

            Private _computer As String

            <CompilerGenerated()>

            Private _mount_type As String

            <CompilerGenerated()>

            Private _assign_type As String

            <CompilerGenerated()>

            Private _filename As String

            Public Property entityt() As String

                Get

                    Return Me._entityt

                End Get

                Set(value As String)

                    Me._entityt = value

                End Set

            End Property

            Public Property entity() As String

                Get

                    Return Me._entity

                End Get

                Set(value As String)

                    Me._entity = value

                End Set

            End Property

            Public Property snapvol() As String

                Get

                    Return Me._snapvol

                End Get

                Set(value As String)

                    Me._snapvol = value

                End Set

            End Property

            Public Property snapvol_file() As AppVolumes.snapvolfile

                Get

                    Return Me._snapvol_file

                End Get

                Set(value As AppVolumes.snapvolfile)

                    Me._snapvol_file = value

                End Set

            End Property

            Public Property volume_type() As String

                Get

                    Return Me._volume_type

                End Get

                Set(value As String)

                    Me._volume_type = value

                End Set

            End Property

            Public Property duration() As String

                Get

                    Return Me._duration

                End Get

                Set(value As String)

                    Me._duration = value

                End Set

            End Property

            Public Property event_time_human() As String

                Get

                    Return Me._event_time_human

                End Get

                Set(value As String)

                    Me._event_time_human = value

                End Set

            End Property

            Public Property computer() As String

                Get

                    Return Me._computer

                End Get

                Set(value As String)

                    Me._computer = value

                End Set

            End Property

            Public Property mount_type() As String

                Get

                    Return Me._mount_type

                End Get

                Set(value As String)

                    Me._mount_type = value

                End Set

            End Property

            Public Property assign_type() As String

                Get

                    Return Me._assign_type

                End Get

                Set(value As String)

                    Me._assign_type = value

                End Set

            End Property

            Public Property filename() As String

                Get

                    Return Me._filename

                End Get

                Set(value As String)

                    Me._filename = value

                End Set

            End Property

        Public Function AcceptAllCertifications(sender As Object, certification As X509Certificate, chain As X509Chain, sslPolicyErrors As SslPolicyErrors) As Boolean

            Return True

        End Function

        End Class

End Class

End Namespace

Sravan_k
Expert
Expert
Jump to solution

Thank you Tschuegy, This code is for just create a 'Form'?

0 Kudos
tschuegy
Enthusiast
Enthusiast
Jump to solution

No, this code will be used in the form. The form is only the GUI. What the GUI should do is that code. You can watch many youtube videos over programming with visual studio.

tschuegy
Enthusiast
Enthusiast
Jump to solution

Here are the complete source code for your request: https://1drv.ms/u/s!An1G6213BZX-gRWDaGK9tPJQigdL

In this zip file is the entire visual studio project. I have my project modified for you. It will only display assigned appstacks.

In the folder AppVolumesSelfService\bin\Debug\ is a config file "AppVolumesListAppStacks.exe.config". Please modify that for your environment.

Tschuegy

Sravan_k
Expert
Expert
Jump to solution

Thank you so much Tschuegy, I did't expect it

0 Kudos
tschuegy
Enthusiast
Enthusiast
Jump to solution

Yes you have to enter the Values of your environment. Create an AD Group and add this group into the AppVolumes Manager:

AppVol_Admins.PNG

Create an AD User an add this user account name into the config file. Replace my AVTestuser with your username and replace AVPW with the password that you have defined during the creation of the AD user. Replace http://AVManager.contoso.com with the URL from your AppVolumes Manager. And at least, replace contoso.com with your Netbios domain. You can see your netbios domain name in the AppVolumes Manager.

AppVol_Domain.PNG

Try it out.

Sravan_k
Expert
Expert
Jump to solution

Thank you Tschuegy, I will try it

0 Kudos
Sravan_k
Expert
Expert
Jump to solution

Hi Tschuegy,

I tried doing it and got the below error

note: I changed url to my environment, even thou it is not working  

0 Kudos