diff --git a/cli/subscribe.go b/cli/subscribe.go
index 284a74d89de56df7c667fd813b4ecd7ef92037f7..031ab104281c6c031ad2dc3c6a403e2a0be86e9a 100644
--- a/cli/subscribe.go
+++ b/cli/subscribe.go
@@ -18,20 +18,20 @@ import (
 
 // Subscribe starts a gNMI subscriber requersting the specified paths on the target and
 // logs the response to stdout. Only 'stream' mode with 'sample' operation supported.
-func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error {
+func Subscribe(address, username, password, deviceName string, sample, heartbeat int64, args ...string) error {
 	sbi := &nucleus.OpenConfig{}
 	tOpts := &nucleus.GnmiTransportOptions{
 		Config: gnmi.Config{
-			Addr:     a,
-			Username: u,
-			Password: p,
+			Addr:     address,
+			Username: username,
+			Password: password,
 			Encoding: gpb.Encoding_JSON_IETF,
 		},
 		SetNode:  sbi.SetNode(),
 		RespChan: make(chan *gpb.SubscribeResponse),
 	}
 
-	device, err := nucleus.NewDevice(sbi, tOpts)
+	device, err := nucleus.NewDevice(sbi, tOpts, deviceName)
 	if err != nil {
 		return err
 	}
@@ -46,7 +46,7 @@ func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error {
 		HeartbeatInterval: uint64(heartbeat * time.Second.Nanoseconds()),
 		Paths:             gnmi.SplitPaths(args),
 		Origin:            "",
-		Target:            a,
+		Target:            address,
 	}
 	done := make(chan os.Signal, 1)
 	signal.Notify(done, syscall.SIGILL, syscall.SIGTERM)
@@ -59,5 +59,6 @@ func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error {
 	fmt.Println("awaiting signal")
 	<-done
 	fmt.Println("exiting")
+
 	return nil
 }
diff --git a/cmd/addDevice.go b/cmd/addDevice.go
index 95180504c5828c06dce7cbb713a204e3acd9275b..d3d65e7edd2a2061e9db8cf9b341832ead84561f 100644
--- a/cmd/addDevice.go
+++ b/cmd/addDevice.go
@@ -36,12 +36,14 @@ import (
 	"github.com/spf13/cobra"
 )
 
+var deviceName string
+
 // addDeviceCmd represents the addDevice command
 var addDeviceCmd = &cobra.Command{
 	Use:   "add-device",
 	Short: "adds a device to the controller",
-	Long: `Adds a device to the controller. 
-	
+	Long: `Adds a device to the controller.
+
 Device address and user credentials need to be provided
 if they diverge from the default credentials.`,
 	RunE: func(cmd *cobra.Command, args []string) error {
@@ -53,10 +55,13 @@ if they diverge from the default credentials.`,
 			"username="+username,
 			"sbi="+cliSbi,
 			"pnd="+cliPnd,
+			"name="+deviceName,
 		)
 	},
 }
 
 func init() {
 	cliCmd.AddCommand(addDeviceCmd)
+
+	addDeviceCmd.PersistentFlags().StringVarP(&deviceName, "device-name", "n", "", "Human readable device name.")
 }
diff --git a/cmd/getDevice.go b/cmd/getDevice.go
index 2daf934073e6f69dc0f8b55971aa747c9eccec13..ac38362886656823f04c0a79c55d3f9d0a15c7b8 100644
--- a/cmd/getDevice.go
+++ b/cmd/getDevice.go
@@ -42,13 +42,13 @@ var getDeviceCmd = &cobra.Command{
 	Args:  cobra.ExactArgs(1),
 	Short: "gets device information from the controller",
 	Long: `Gets device information from the controller.
-	
-Device UUID needs to be specified as positional argument.`,
+
+Device UUID or name needs to be specified as positional argument.`,
 	RunE: func(cmd *cobra.Command, args []string) error {
 		return cli.HTTPGet(
 			apiEndpoint,
 			"getDevice",
-			"uuid="+args[0],
+			"identifier="+args[0],
 			"sbi="+cliSbi,
 			"pnd="+cliPnd,
 		)
diff --git a/cmd/init.go b/cmd/init.go
index 6a4b3e9bab78477c71efc80a075b3855b1a3265d..f39f09287c4517ed33c027cac6311a0e9be2585b 100644
--- a/cmd/init.go
+++ b/cmd/init.go
@@ -41,7 +41,7 @@ var initCmd = &cobra.Command{
 	Use:   "init",
 	Short: "initialise SBI and PND",
 	Long: `Initialise SBI and PND and saves values to config file.
-	
+
 Same as invoking "gosdn cli" without any arguments`,
 	RunE: func(cmd *cobra.Command, args []string) error {
 		return cli.HTTPGet(apiEndpoint, "init")
diff --git a/cmd/request.go b/cmd/request.go
index 54dd12becaad214a2d19f36d9da6a0a2cf7ac174..3bf82b6c69705fdd1cfb1f7396cd79977ea87de8 100644
--- a/cmd/request.go
+++ b/cmd/request.go
@@ -42,7 +42,7 @@ var requestCmd = &cobra.Command{
 	Args:  cobra.ExactArgs(1),
 	Short: "requests a path from a specified device on the controller",
 	Long: `Requests a path from a specified device on the controller.
-	
+
 The request path is passed as positional argument.`,
 	RunE: func(cmd *cobra.Command, args []string) error {
 		return cli.HTTPGet(
diff --git a/cmd/requestAll.go b/cmd/requestAll.go
index 11234826ed412ed507e9711b7b4af84b379c856e..67fe1da1c40c884da0ac35c6f8d1c38d6260e711 100644
--- a/cmd/requestAll.go
+++ b/cmd/requestAll.go
@@ -43,7 +43,7 @@ var requestAllCmd = &cobra.Command{
 	Short: "requests specified path from all devices on the controller",
 	Long: `Requests a path from all devices on the controller known by
 the controller.
-	
+
 The request path is passed as positional argument.`,
 	RunE: func(cmd *cobra.Command, args []string) error {
 		return cli.HTTPGet(
diff --git a/cmd/subscribe.go b/cmd/subscribe.go
index a641b7fb4f4abffebd4e6848ae5cf6343644d276..63e7a9ac5c131d862253d34f7ba46e62cd5b2374 100644
--- a/cmd/subscribe.go
+++ b/cmd/subscribe.go
@@ -47,7 +47,7 @@ var subscribeCmd = &cobra.Command{
 
 Only 'stream' mode with 'sample' operation supported.`,
 	RunE: func(cmd *cobra.Command, args []string) error {
-		return cli.Subscribe(address, username, password, sampleInterval, heartbeatInterval, args...)
+		return cli.Subscribe(address, username, password, "", sampleInterval, heartbeatInterval, args...)
 	},
 }
 
diff --git a/go.mod b/go.mod
index 8e06b5944cab2bd7ffa365c59d78b8295043bc1f..a8879d2d35c76d7fae7ca783814d6ec407cc53b4 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.14
 require (
 	code.fbi.h-da.de/cocsn/yang-models v0.0.7
 	github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a
+	github.com/docker/docker v1.13.1
 	github.com/golang/protobuf v1.5.0
 	github.com/google/gnxi v0.0.0-20201221102247-c26672548161
 	github.com/google/uuid v1.1.2
diff --git a/go.sum b/go.sum
index 611ef282280814b75535b07660de63a3df5b77fa..c92b0a484bbfc28c2259f0cca50497156779bb2c 100644
--- a/go.sum
+++ b/go.sum
@@ -84,6 +84,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
 github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
diff --git a/http.go b/http.go
index 92ce1890a2a0d5585d0093f6614fa727d919184c..cc44a1059dd61e717900ef725af22718e95b9b9d 100644
--- a/http.go
+++ b/http.go
@@ -1,19 +1,22 @@
 package gosdn
 
 import (
+	"context"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"time"
+
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
-	"context"
-	"fmt"
+
 	"github.com/google/uuid"
+
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 	log "github.com/sirupsen/logrus"
-	"io"
-	"net/http"
-	"net/url"
-	"time"
 )
 
 var apiOpmap = map[string]types.Operation{
@@ -119,15 +122,26 @@ func httpApi(writer http.ResponseWriter, request *http.Request) {
 			SetNode:   httpSbi.SetNode(),
 			Unmarshal: httpSbi.(*nucleus.OpenConfig).Unmarshal(),
 			RespChan:  make(chan *gpb.SubscribeResponse),
-		})
+		},
+			query.Get("name"),
+		)
+		if err != nil {
+			writer.WriteHeader(http.StatusInternalServerError)
+			log.Error(err)
+
+			return
+		}
+
 		err = httpPnd.AddDevice(d)
 		if err != nil {
 			writer.WriteHeader(http.StatusInternalServerError)
 			log.Error(err)
+
 			return
 		}
 		writer.WriteHeader(http.StatusCreated)
 		fmt.Fprintf(writer, "device added\n")
+		fmt.Fprintf(writer, "Name: %s\n", d.Name)
 		fmt.Fprintf(writer, "UUID: %v\n", d.UUID)
 	case "request":
 		err = httpPnd.Request(id, query.Get("path"))
@@ -156,7 +170,9 @@ func httpApi(writer http.ResponseWriter, request *http.Request) {
 		}
 		writer.WriteHeader(http.StatusOK)
 	case "getDevice":
-		device, err := httpPnd.MarshalDevice(id)
+		deviceIdentifier := query.Get("identifier")
+
+		device, err := httpPnd.MarshalDevice(deviceIdentifier)
 		if err != nil {
 			switch err.(type) {
 			case *errors.ErrNotFound:
@@ -165,10 +181,13 @@ func httpApi(writer http.ResponseWriter, request *http.Request) {
 				writer.WriteHeader(http.StatusInternalServerError)
 			}
 			log.Error(err)
+
 			return
 		}
+
 		writer.Header().Set("Content-Type", "application/json")
 		fmt.Fprintf(writer, "%v", device)
+
 	case "getIDs":
 
 		pnds := c.pndc.UUIDs()
diff --git a/http_test.go b/http_test.go
index 47a7a3e12ecc20da64c1f5476ea938d6783c44d7..8b80c8b4e1286b241b5254de5c496ba587e23455 100644
--- a/http_test.go
+++ b/http_test.go
@@ -35,6 +35,7 @@ func testSetupHTTP() {
 	}
 	args = "&uuid=" + mdid.String() + "&pnd=" + defaultPndID.String() + "&sbi=" + defaultSbiID.String()
 	argsNotFound = "&uuid=" + uuid.New().String() + "&pnd=" + defaultPndID.String() + "&sbi=" + defaultSbiID.String()
+	argsNotFoundGetDevice = "&identifier=" + uuid.New().String() + "&pnd=" + defaultPndID.String() + "&sbi=" + defaultSbiID.String()
 	if err := c.sbic.Add(sbi); err != nil {
 		log.Fatal(err)
 	}
@@ -119,7 +120,7 @@ func Test_httpApi(t *testing.T) {
 		},
 		{
 			name:    "get-device not found",
-			request: apiEndpoint + "/api?q=getDevice" + argsNotFound,
+			request: apiEndpoint + "/api?q=getDevice" + argsNotFoundGetDevice,
 			want:    &http.Response{StatusCode: http.StatusNotFound},
 			wantErr: false,
 		},
diff --git a/initialise_test.go b/initialise_test.go
index 5fbb298a7aa6a4cbc30aff8a80695aa1647eb34a..74effe95eed2b368abc0bdf59ef6c527c7ffce7e 100644
--- a/initialise_test.go
+++ b/initialise_test.go
@@ -30,6 +30,7 @@ var httpTestDevice nucleus.Device
 
 var args string
 var argsNotFound string
+var argsNotFoundGetDevice string
 
 var mockContext = mock.MatchedBy(func(ctx context.Context) bool { return true })
 
diff --git a/nucleus/device.go b/nucleus/device.go
index 0c03706fc2c1866784b58d9689b25283f70f5465..ccfa738f62d99f6cb132ee25222726131e573e99 100644
--- a/nucleus/device.go
+++ b/nucleus/device.go
@@ -2,6 +2,7 @@ package nucleus
 
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+	"github.com/docker/docker/pkg/namesgenerator"
 	"github.com/google/uuid"
 	"github.com/openconfig/ygot/ygot"
 )
@@ -20,20 +21,28 @@ type Device struct {
 
 	// Transport is the device's Transport implementation
 	Transport Transport
+
+	// Name is the device's human readable name
+	Name string
 }
 
 // NewDevice creates a Device
-func NewDevice(sbi SouthboundInterface, opts TransportOptions) (*Device, error) {
+func NewDevice(sbi SouthboundInterface, opts TransportOptions, name string) (*Device, error) {
 	var transport Transport
 	var err error
-	switch o := opts.(type) {
+
+	if name == "" {
+		name = namesgenerator.GetRandomName(0)
+	}
+
+	switch opts := opts.(type) {
 	case *GnmiTransportOptions:
-		transport, err = NewGnmiTransport(o)
+		transport, err = NewGnmiTransport(opts)
 		if err != nil {
 			return nil, err
 		}
 	default:
-		return nil, &errors.ErrInvalidTransportOptions{Opt: o}
+		return nil, &errors.ErrInvalidTransportOptions{Opt: opts}
 
 	}
 	return &Device{
@@ -41,6 +50,7 @@ func NewDevice(sbi SouthboundInterface, opts TransportOptions) (*Device, error)
 		GoStruct:  sbi.Schema().Root,
 		SBI:       sbi,
 		Transport: transport,
+		Name:      name,
 	}, nil
 }
 
diff --git a/nucleus/device_test.go b/nucleus/device_test.go
index 829c60c5d53f53611d8dfb72f411145769fca58b..1b4a6fd0c7f5a0174adda177073e7a22cdb1a6d4 100644
--- a/nucleus/device_test.go
+++ b/nucleus/device_test.go
@@ -16,6 +16,7 @@ func TestDevice_Id(t *testing.T) {
 		SBI       SouthboundInterface
 		Transport Transport
 		UUID      uuid.UUID
+		Name      string
 	}
 	tests := []struct {
 		name   string
@@ -37,6 +38,7 @@ func TestDevice_Id(t *testing.T) {
 				SBI:       tt.fields.SBI,
 				Transport: tt.fields.Transport,
 				UUID:      tt.fields.UUID,
+				Name:      tt.fields.Name,
 			}
 			if got := d.ID(); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("ID() = %v, want %v", got, tt.want)
@@ -50,6 +52,7 @@ func TestNewDevice(t *testing.T) {
 	type args struct {
 		sbi  SouthboundInterface
 		opts TransportOptions
+		name string
 	}
 	tests := []struct {
 		name    string
@@ -68,6 +71,7 @@ func TestNewDevice(t *testing.T) {
 						Password: "test",
 					},
 				},
+				name: "MyDevice",
 			},
 			want: &Device{
 				GoStruct: &openconfig.Device{},
@@ -82,12 +86,13 @@ func TestNewDevice(t *testing.T) {
 						},
 					},
 				},
+				Name: "MyDevice",
 			},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := NewDevice(tt.args.sbi, tt.args.opts)
+			got, err := NewDevice(tt.args.sbi, tt.args.opts, tt.args.name)
 			if err != nil {
 				t.Error(err)
 			}
diff --git a/nucleus/errors/errors.go b/nucleus/errors/errors.go
index 3aad202118e0bceb2b4e91dd34ce075c1ed454e5..4cc6ca1c61d8cb1d82d125030fabbc8840c74788 100644
--- a/nucleus/errors/errors.go
+++ b/nucleus/errors/errors.go
@@ -41,6 +41,15 @@ func (e *ErrAlreadyExists) Error() string {
 	return fmt.Sprintf("%v already exists", e.Item)
 }
 
+// ErrInvalidUUID implements the Error interface and is called if a UUID is not valid.
+type ErrInvalidUUID struct {
+	DeviceName string
+}
+
+func (e *ErrInvalidUUID) Error() string {
+	return fmt.Sprintf("UUID not valid")
+}
+
 // ErrInvalidTypeAssertion implements the Error interface and is called if the
 // type of a storable item does not correspond to the expected type.
 type ErrInvalidTypeAssertion struct {
diff --git a/nucleus/initialise_test.go b/nucleus/initialise_test.go
index 85b938a0d14aa442c196e020b9f413b8095bb9bb..dc60751e1f3a12d04fab39e4ae4e67d438202476 100644
--- a/nucleus/initialise_test.go
+++ b/nucleus/initialise_test.go
@@ -129,7 +129,7 @@ func newPnd() pndImplementation {
 		name:             "default",
 		description:      "default test pnd",
 		sbic:             SbiStore{store{}},
-		devices:          DeviceStore{store{}},
+		devices:          NewDeviceStore(),
 		pendingChanges:   ChangeStore{store{}},
 		committedChanges: ChangeStore{store{}},
 		confirmedChanges: ChangeStore{store{}},
diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go
index e3d535d81d7dfee3557f6ce2f7d7bdd94ab7f6f1..4c16117293b9b0eb38a48cf49ea39c5c13cdc688 100644
--- a/nucleus/principalNetworkDomain.go
+++ b/nucleus/principalNetworkDomain.go
@@ -23,7 +23,7 @@ type PrincipalNetworkDomain interface {
 	AddSbi(interface{}) error
 	RemoveSbi(uuid.UUID) error
 	AddDevice(interface{}) error
-	GetDevice(uuid uuid.UUID) (ygot.GoStruct, error)
+	GetDevice(identifier string) (*Device, error)
 	RemoveDevice(uuid.UUID) error
 	Devices() []uuid.UUID
 	ChangeOND(uuid uuid.UUID, operation interface{}, path string, value ...string) error
@@ -31,7 +31,7 @@ type PrincipalNetworkDomain interface {
 	RequestAll(string) error
 	GetName() string
 	GetDescription() string
-	MarshalDevice(uuid.UUID) (string, error)
+	MarshalDevice(string) (string, error)
 	ContainsDevice(uuid.UUID) bool
 	GetSBIs() interface{}
 	ID() uuid.UUID
@@ -47,7 +47,7 @@ func NewPND(name, description string, id uuid.UUID, sbi SouthboundInterface) (Pr
 		name:             name,
 		description:      description,
 		sbic:             SbiStore{store{}},
-		devices:          DeviceStore{store{}},
+		devices:          NewDeviceStore(),
 		pendingChanges:   ChangeStore{store{}},
 		committedChanges: ChangeStore{store{}},
 		confirmedChanges: ChangeStore{store{}},
@@ -64,7 +64,7 @@ type pndImplementation struct {
 	name             string
 	description      string
 	sbic             SbiStore
-	devices          DeviceStore
+	devices          *DeviceStore
 	pendingChanges   ChangeStore
 	committedChanges ChangeStore
 	confirmedChanges ChangeStore
@@ -172,7 +172,7 @@ func (pnd *pndImplementation) RemoveSbi(id uuid.UUID) error {
 	return pnd.removeSbi(id)
 }
 
-//AddDevice adds a new device to the PND
+// AddDevice adds a new device to the PND
 func (pnd *pndImplementation) AddDevice(device interface{}) error {
 	d, ok := device.(*Device)
 	if !ok {
@@ -184,12 +184,20 @@ func (pnd *pndImplementation) AddDevice(device interface{}) error {
 	return pnd.addDevice(d)
 }
 
-func (pnd *pndImplementation) GetDevice(uuid uuid.UUID) (ygot.GoStruct, error) {
-	d, err := pnd.devices.Get(uuid)
+func (pnd *pndImplementation) GetDevice(identifier string) (*Device, error) {
+	d, err := pnd.devices.Get(FromString(identifier))
 	if err != nil {
 		return nil, err
 	}
-	return ygot.DeepCopy(d.GoStruct)
+
+	copiedGoStruct, err := ygot.DeepCopy(d.GoStruct)
+	if err != nil {
+		return nil, err
+	}
+
+	copiedDevice := &Device{Name: d.Name, UUID: d.UUID, GoStruct: copiedGoStruct}
+
+	return copiedDevice, nil
 }
 
 // RemoveDevice removes a device from the PND
@@ -212,36 +220,40 @@ func (pnd *pndImplementation) removeSbi(id uuid.UUID) error {
 }
 
 func (pnd *pndImplementation) addDevice(device *Device) error {
-	return pnd.devices.Add(device)
-}
+	err := pnd.devices.Add(device, device.Name)
+	if err != nil {
+		return err
+	}
 
-func (pnd *pndImplementation) getDevice(id uuid.UUID) (*Device, error) {
-	return pnd.devices.Get(id)
+	return nil
 }
 
 func (pnd *pndImplementation) removeDevice(id uuid.UUID) error {
 	return pnd.devices.Delete(id)
 }
 
-func (pnd *pndImplementation) MarshalDevice(uuid uuid.UUID) (string, error) {
-	d, err := pnd.getDevice(uuid)
+func (pnd *pndImplementation) MarshalDevice(identifier string) (string, error) {
+	foundDevice, err := pnd.devices.Get(FromString(identifier))
 	if err != nil {
 		return "", err
 	}
-	jsonTree, err := json.MarshalIndent(d.GoStruct, "", "\t")
+
+	jsonTree, err := json.MarshalIndent(foundDevice.GoStruct, "", "\t")
 	if err != nil {
 		return "", err
 	}
 	log.WithFields(log.Fields{
-		"pnd":    pnd.id,
-		"device": uuid,
+		"pnd":        pnd.id,
+		"Identifier": identifier,
+		"Name":       foundDevice.Name,
 	}).Info("marshalled device")
+
 	return string(jsonTree), nil
 }
 
 // Request sends a get request to a specific device
 func (pnd *pndImplementation) Request(uuid uuid.UUID, path string) error {
-	d, err := pnd.getDevice(uuid)
+	d, err := pnd.devices.Get(FromString(uuid.String()))
 	if err != nil {
 		return err
 	}
@@ -273,12 +285,15 @@ func (pnd *pndImplementation) RequestAll(path string) error {
 
 // ChangeOND creates a change from the provided Operation, path and value. The Change is pending and
 func (pnd *pndImplementation) ChangeOND(uuid uuid.UUID, operation interface{}, path string, value ...string) error {
-	d, err := pnd.getDevice(uuid)
+	d, err := pnd.devices.Get(FromString(uuid.String()))
 	if err != nil {
 		return err
 	}
 	cpy, err := ygot.DeepCopy(d.GoStruct)
 	ygot.BuildEmptyTree(cpy)
+	if err != nil {
+		return err
+	}
 
 	p, err := ygot.StringToStructuredPath(path)
 	if err != nil {
diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go
index 17d5c0a30232b69ec82e180fc2fa75706d3d66c5..88341b5b66669e0e184954af6292a90082c1a46f 100644
--- a/nucleus/principalNetworkDomain_test.go
+++ b/nucleus/principalNetworkDomain_test.go
@@ -224,7 +224,7 @@ func Test_pndImplementation_ContainsDevice(t *testing.T) {
 		t.Run(tt.name, func(t *testing.T) {
 			pnd := newPnd()
 			if tt.name != "fails empty" {
-				if err := pnd.devices.Add(tt.args.device); err != nil {
+				if err := pnd.devices.Add(tt.args.device, "test"); err != nil {
 					t.Error(err)
 				}
 			}
@@ -243,7 +243,7 @@ func Test_pndImplementation_Destroy(t *testing.T) {
 		name        string
 		description string
 		sbi         SbiStore
-		devices     DeviceStore
+		devices     *DeviceStore
 	}
 	tests := []struct {
 		name    string
@@ -347,7 +347,7 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) {
 			if err := pnd.addDevice(d); err != nil {
 				t.Error(err)
 			}
-			got, err := pnd.MarshalDevice(tt.args.uuid)
+			got, err := pnd.MarshalDevice(tt.args.uuid.String())
 			if (err != nil) != tt.wantErr {
 				t.Errorf("MarshalDevice() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -413,7 +413,7 @@ func Test_pndImplementation_RemoveSbi(t *testing.T) {
 				name:        "test-remove-sbi",
 				description: "test-remove-sbi",
 				sbic:        SbiStore{store{}},
-				devices:     DeviceStore{store{}},
+				devices:     NewDeviceStore(),
 				id:          defaultPndID,
 			}
 			if tt.name != "fails empty" {
@@ -661,7 +661,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 func Test_pndImplementation_GetDevice(t *testing.T) {
 	pnd := newPnd()
 	sbi := NewSBI(types.Openconfig)
-	d, err := NewDevice(sbi, &GnmiTransportOptions{})
+	d, err := NewDevice(sbi, &GnmiTransportOptions{}, "")
 	if err != nil {
 		t.Error(err)
 		return
@@ -694,14 +694,68 @@ func Test_pndImplementation_GetDevice(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := pnd.GetDevice(tt.args.uuid)
+			foundDevice, err := pnd.GetDevice(tt.args.uuid.String())
 			if (err != nil) != tt.wantErr {
 				t.Errorf("GetDevice() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("GetDevice() got = %v, want %v", got, tt.want)
+			if foundDevice != nil {
+				if !reflect.DeepEqual(foundDevice.GoStruct, tt.want) {
+					t.Errorf("GetDevice() got = %v, want %v", foundDevice.GoStruct, tt.want)
+				}
 			}
+
+		})
+	}
+}
+
+func Test_pndImplementation_GetDeviceByName(t *testing.T) {
+	p := newPnd()
+	sbi := NewSBI(types.Openconfig)
+	d, err := NewDevice(sbi, &GnmiTransportOptions{}, "my-device")
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if err = p.addDevice(d); err != nil {
+		t.Error(err)
+		return
+	}
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    ygot.GoStruct
+		wantErr bool
+	}{
+		{
+			name:    "default",
+			args:    args{name: d.Name},
+			want:    sbi.Schema().Root,
+			wantErr: false,
+		},
+		{
+			name:    "device not found",
+			args:    args{name: "test-device"},
+			want:    nil,
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			foundDevice, err := p.GetDevice(tt.args.name)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GetDeviceByName() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if foundDevice != nil {
+				if !reflect.DeepEqual(foundDevice.GoStruct, tt.want) {
+					t.Errorf("GetDeviceByName() got = %v, want %v", foundDevice.GoStruct, tt.want)
+				}
+			}
+
 		})
 	}
 }
diff --git a/nucleus/store.go b/nucleus/store.go
index 291ed361c39491e49c499a2cefab1e556df88578..639762d43210259758d94970e538a391cd3a84b5 100644
--- a/nucleus/store.go
+++ b/nucleus/store.go
@@ -1,6 +1,7 @@
 package nucleus
 
 import (
+	"fmt"
 	"reflect"
 	"sync"
 
@@ -43,7 +44,7 @@ func NewSbiStore() *SbiStore {
 
 // NewDeviceStore returns a DeviceStore
 func NewDeviceStore() *DeviceStore {
-	return &DeviceStore{store{}}
+	return &DeviceStore{store: store{}, deviceNameToUUIDLookup: make(map[string]uuid.UUID)}
 }
 
 // NewChangeStore returns a ChangeStore
@@ -170,13 +171,33 @@ func (s PndStore) Get(id uuid.UUID) (PrincipalNetworkDomain, error) {
 
 // DeviceStore is used to store Devices
 type DeviceStore struct {
+	deviceNameToUUIDLookup map[string]uuid.UUID
 	store
 }
 
 // Get takes a Device's UUID and returns the Device. If the requested
 // Device does not exist an error is returned.
-func (s DeviceStore) Get(id uuid.UUID) (*Device, error) {
-	item, err := s.store.Get(id)
+func (s DeviceStore) Get(id uuid.UUID, parseErrors ...error) (*Device, error) {
+	var foundID uuid.UUID
+
+	foundID = id
+
+	for _, parseErrs := range parseErrors {
+		if parseErrs != nil {
+			switch e := parseErrs.(type) {
+			case *errors.ErrInvalidUUID:
+				myID, ok := s.deviceNameToUUIDLookup[e.DeviceName]
+				if !ok {
+					log.Debug(fmt.Sprintf("no device named %s found", foundID))
+					return nil, &errors.ErrNotFound{}
+				}
+
+				foundID = myID
+			}
+		}
+	}
+
+	item, err := s.store.Get(foundID)
 	if err != nil {
 		return nil, err
 	}
@@ -189,10 +210,72 @@ func (s DeviceStore) Get(id uuid.UUID) (*Device, error) {
 	}
 	log.WithFields(log.Fields{
 		"uuid": id,
+		"name": device.Name,
 	}).Debug("device was accessed")
+
 	return device, nil
 }
 
+// FromString is a helper to check if a provided string as a valid UUID or a name.
+func FromString(id string) (uuid.UUID, error) {
+	idAsUUID, err := uuid.Parse(id)
+
+	// id is no UUID therefore it could be a device name.
+	// The name will be returned within the error.
+	if err != nil {
+		log.WithFields(log.Fields{
+			"identifier": id,
+		}).Debug(err)
+		return uuid.Nil, &errors.ErrInvalidUUID{DeviceName: id}
+	}
+
+	return idAsUUID, nil
+}
+
+// Add adds a device to the device store.
+// It also adds the name of the device to the lookup table.
+func (s DeviceStore) Add(item Storable, name string) error {
+	if s.Exists(item.ID()) {
+		return &errors.ErrAlreadyExists{Item: item}
+	}
+
+	s.deviceNameToUUIDLookup[name] = item.ID()
+
+	storeLock.Lock()
+	s.store[item.ID()] = item
+	storeLock.Unlock()
+
+	log.WithFields(log.Fields{
+		"type": reflect.TypeOf(item),
+		"uuid": item.ID(),
+	}).Debug("storable was added")
+
+	return nil
+}
+
+// Delete deletes a device from the device store.
+func (s DeviceStore) Delete(id uuid.UUID) error {
+	if !s.Exists(id) {
+		return &errors.ErrNotFound{ID: id}
+	}
+
+	storeLock.Lock()
+	delete(s.store, id)
+	storeLock.Unlock()
+
+	for key, value := range s.deviceNameToUUIDLookup {
+		if value == id {
+			delete(s.deviceNameToUUIDLookup, key)
+		}
+	}
+
+	log.WithFields(log.Fields{
+		"uuid": id,
+	}).Debug("storable was deleted")
+
+	return nil
+}
+
 // ChangeStore is used to store Changes
 type ChangeStore struct {
 	store
diff --git a/nucleus/store_test.go b/nucleus/store_test.go
index f2db1ed61741fb75f4ab4360bc192610573f3697..18a13fd4cc1b08552fe030efb7e02a894fb73028 100644
--- a/nucleus/store_test.go
+++ b/nucleus/store_test.go
@@ -423,9 +423,11 @@ func Test_deviceStore_get(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			s := DeviceStore{
-				store: tt.fields.store,
+				store:                  tt.fields.store,
+				deviceNameToUUIDLookup: make(map[string]uuid.UUID),
 			}
-			got, err := s.Get(tt.args.id)
+
+			got, err := s.Get(FromString(tt.args.id.String()))
 			if (err != nil) != tt.wantErr {
 				t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr)
 				return