@pnp/cli-microsoft365 7.0.0-beta.99e75a7 → 7.0.0-beta.b2eab57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/cli/Cli.js +19 -2
  2. package/dist/m365/spo/commands/file/file-move.js +73 -97
  3. package/dist/m365/spo/commands/folder/folder-copy.js +89 -45
  4. package/dist/m365/spo/commands/folder/folder-move.js +89 -47
  5. package/dist/m365/spo/commands/propertybag/propertybag-base.js +63 -59
  6. package/dist/m365/spo/commands/propertybag/propertybag-remove.js +28 -31
  7. package/dist/m365/spo/commands/site/FlowsPolicy.js +7 -0
  8. package/dist/m365/spo/commands/site/site-ensure.js +3 -3
  9. package/dist/m365/spo/commands/site/site-hubsite-disconnect.js +22 -22
  10. package/dist/m365/spo/commands/site/site-list.js +29 -39
  11. package/dist/m365/spo/commands/site/site-set.js +58 -47
  12. package/dist/m365/spo/commands/theme/theme-remove.js +24 -24
  13. package/dist/m365/spo/commands/theme/theme-set.js +0 -1
  14. package/dist/m365/spo/commands/user/user-remove.js +27 -27
  15. package/dist/m365/spo/commands/web/web-reindex.js +35 -42
  16. package/dist/m365/spo/commands/web/web-remove.js +21 -21
  17. package/dist/m365/spo/commands/web/web-roleassignment-add.js +16 -31
  18. package/dist/m365/spo/commands/web/web-roleassignment-remove.js +33 -44
  19. package/dist/m365/spo/commands/web/web-roleinheritance-break.js +18 -18
  20. package/dist/m365/spo/commands/web/web-roleinheritance-reset.js +19 -19
  21. package/dist/m365/yammer/commands/message/message-like-set.js +27 -28
  22. package/dist/m365/yammer/commands/message/message-list.js +62 -81
  23. package/dist/m365/yammer/commands/message/message-remove.js +18 -18
  24. package/dist/m365/yammer/commands/yammer-search.js +53 -69
  25. package/dist/utils/spo.js +12 -53
  26. package/docs/docs/cmd/spo/file/file-move.mdx +36 -18
  27. package/docs/docs/cmd/spo/folder/folder-copy.mdx +39 -12
  28. package/docs/docs/cmd/spo/folder/folder-move.mdx +40 -13
  29. package/docs/docs/cmd/spo/site/site-ensure.mdx +1 -1
  30. package/npm-shrinkwrap.json +1 -1
  31. package/package.json +1 -1
@@ -24,34 +24,9 @@ class YammerMessageLikeSetCommand extends YammerCommand {
24
24
  __classPrivateFieldGet(this, _YammerMessageLikeSetCommand_instances, "m", _YammerMessageLikeSetCommand_initValidators).call(this);
25
25
  }
26
26
  async commandAction(logger, args) {
27
- const executeLikeAction = async () => {
28
- const endpoint = `${this.resource}/v1/messages/liked_by/current.json`;
29
- const requestOptions = {
30
- url: endpoint,
31
- headers: {
32
- accept: 'application/json;odata.metadata=none',
33
- 'content-type': 'application/json;odata=nometadata'
34
- },
35
- responseType: 'json',
36
- data: {
37
- message_id: args.options.messageId
38
- }
39
- };
40
- try {
41
- if (args.options.enable !== false) {
42
- await request.post(requestOptions);
43
- }
44
- else {
45
- await request.delete(requestOptions);
46
- }
47
- }
48
- catch (err) {
49
- this.handleRejectedODataJsonPromise(err);
50
- }
51
- };
52
27
  if (args.options.enable === false) {
53
28
  if (args.options.force) {
54
- await executeLikeAction();
29
+ await this.executeLikeAction(args.options);
55
30
  }
56
31
  else {
57
32
  const messagePrompt = `Are you sure you want to unlike message ${args.options.messageId}?`;
@@ -62,12 +37,36 @@ class YammerMessageLikeSetCommand extends YammerCommand {
62
37
  message: messagePrompt
63
38
  });
64
39
  if (result.continue) {
65
- await executeLikeAction();
40
+ await this.executeLikeAction(args.options);
66
41
  }
67
42
  }
68
43
  }
69
44
  else {
70
- await executeLikeAction();
45
+ await this.executeLikeAction(args.options);
46
+ }
47
+ }
48
+ async executeLikeAction(options) {
49
+ const requestOptions = {
50
+ url: `${this.resource}/v1/messages/liked_by/current.json`,
51
+ headers: {
52
+ accept: 'application/json;odata.metadata=none',
53
+ 'content-type': 'application/json;odata=nometadata'
54
+ },
55
+ responseType: 'json',
56
+ data: {
57
+ message_id: options.messageId
58
+ }
59
+ };
60
+ try {
61
+ if (options.enable !== false) {
62
+ await request.post(requestOptions);
63
+ }
64
+ else {
65
+ await request.delete(requestOptions);
66
+ }
67
+ }
68
+ catch (err) {
69
+ this.handleRejectedODataJsonPromise(err);
71
70
  }
72
71
  }
73
72
  }
@@ -25,91 +25,72 @@ class YammerMessageListCommand extends YammerCommand {
25
25
  __classPrivateFieldGet(this, _YammerMessageListCommand_instances, "m", _YammerMessageListCommand_initOptions).call(this);
26
26
  __classPrivateFieldGet(this, _YammerMessageListCommand_instances, "m", _YammerMessageListCommand_initValidators).call(this);
27
27
  }
28
- getAllItems(logger, args, messageId) {
29
- return new Promise((resolve, reject) => {
30
- let endpoint = `${this.resource}/v1`;
31
- if (args.options.threadId) {
32
- endpoint += `/messages/in_thread/${args.options.threadId}.json`;
33
- }
34
- else if (args.options.groupId) {
35
- endpoint += `/messages/in_group/${args.options.groupId}.json`;
36
- }
37
- else {
38
- if (!args.options.feedType) {
39
- args.options.feedType = "All";
40
- }
41
- switch (args.options.feedType) {
42
- case 'Top':
43
- endpoint += `/messages/algo.json`;
44
- break;
45
- case 'My':
46
- endpoint += `/messages/my_feed.json`;
47
- break;
48
- case 'Following':
49
- endpoint += `/messages/following.json`;
50
- break;
51
- case 'Sent':
52
- endpoint += `/messages/sent.json`;
53
- break;
54
- case 'Private':
55
- endpoint += `/messages/private.json`;
56
- break;
57
- case 'Received':
58
- endpoint += `/messages/received.json`;
59
- break;
60
- default:
61
- endpoint += `/messages.json`;
62
- }
28
+ async getAllItems(logger, args, messageId) {
29
+ let endpoint = `${this.resource}/v1`;
30
+ if (args.options.threadId) {
31
+ endpoint += `/messages/in_thread/${args.options.threadId}.json`;
32
+ }
33
+ else if (args.options.groupId) {
34
+ endpoint += `/messages/in_group/${args.options.groupId}.json`;
35
+ }
36
+ else {
37
+ if (!args.options.feedType) {
38
+ args.options.feedType = "All";
63
39
  }
64
- if (messageId !== -1) {
65
- endpoint += `?older_than=${messageId}`;
40
+ switch (args.options.feedType) {
41
+ case 'Top':
42
+ endpoint += `/messages/algo.json`;
43
+ break;
44
+ case 'My':
45
+ endpoint += `/messages/my_feed.json`;
46
+ break;
47
+ case 'Following':
48
+ endpoint += `/messages/following.json`;
49
+ break;
50
+ case 'Sent':
51
+ endpoint += `/messages/sent.json`;
52
+ break;
53
+ case 'Private':
54
+ endpoint += `/messages/private.json`;
55
+ break;
56
+ case 'Received':
57
+ endpoint += `/messages/received.json`;
58
+ break;
59
+ default:
60
+ endpoint += `/messages.json`;
66
61
  }
67
- else if (args.options.olderThanId) {
68
- endpoint += `?older_than=${args.options.olderThanId}`;
62
+ }
63
+ if (messageId !== -1) {
64
+ endpoint += `?older_than=${messageId}`;
65
+ }
66
+ else if (args.options.olderThanId) {
67
+ endpoint += `?older_than=${args.options.olderThanId}`;
68
+ }
69
+ if (args.options.threaded) {
70
+ if (endpoint.indexOf("?") > -1) {
71
+ endpoint += "&";
69
72
  }
70
- if (args.options.threaded) {
71
- if (endpoint.indexOf("?") > -1) {
72
- endpoint += "&";
73
- }
74
- else {
75
- endpoint += "?";
76
- }
77
- endpoint += `threaded=true`;
73
+ else {
74
+ endpoint += "?";
78
75
  }
79
- const requestOptions = {
80
- url: endpoint,
81
- headers: {
82
- accept: 'application/json;odata.metadata=none',
83
- 'content-type': 'application/json;odata=nometadata'
84
- },
85
- responseType: 'json'
86
- };
87
- request
88
- .get(requestOptions)
89
- .then((res) => {
90
- this.items = this.items.concat(res.messages);
91
- if (args.options.limit && this.items.length > args.options.limit) {
92
- this.items = this.items.slice(0, args.options.limit);
93
- resolve();
94
- }
95
- else {
96
- if (res.meta.older_available === true) {
97
- this
98
- .getAllItems(logger, args, this.items[this.items.length - 1].id)
99
- .then(() => {
100
- resolve();
101
- }, (err) => {
102
- reject(err);
103
- });
104
- }
105
- else {
106
- resolve();
107
- }
108
- }
109
- }, (err) => {
110
- reject(err);
111
- });
112
- });
76
+ endpoint += `threaded=true`;
77
+ }
78
+ const requestOptions = {
79
+ url: endpoint,
80
+ headers: {
81
+ accept: 'application/json;odata.metadata=none',
82
+ 'content-type': 'application/json;odata=nometadata'
83
+ },
84
+ responseType: 'json'
85
+ };
86
+ const res = await request.get(requestOptions);
87
+ this.items = this.items.concat(res.messages);
88
+ if (args.options.limit && this.items.length > args.options.limit) {
89
+ this.items = this.items.slice(0, args.options.limit);
90
+ }
91
+ else if ((res.meta.older_available === true)) {
92
+ await this.getAllItems(logger, args, this.items[this.items.length - 1].id);
93
+ }
113
94
  }
114
95
  async commandAction(logger, args) {
115
96
  this.items = []; // this will reset the items array in interactive mode
@@ -23,24 +23,8 @@ class YammerMessageRemoveCommand extends YammerCommand {
23
23
  __classPrivateFieldGet(this, _YammerMessageRemoveCommand_instances, "m", _YammerMessageRemoveCommand_initValidators).call(this);
24
24
  }
25
25
  async commandAction(logger, args) {
26
- const removeMessage = async () => {
27
- try {
28
- const requestOptions = {
29
- url: `${this.resource}/v1/messages/${args.options.id}.json`,
30
- headers: {
31
- accept: 'application/json;odata.metadata=none',
32
- 'content-type': 'application/json;odata=nometadata'
33
- },
34
- responseType: 'json'
35
- };
36
- await request.delete(requestOptions);
37
- }
38
- catch (err) {
39
- this.handleRejectedODataJsonPromise(err);
40
- }
41
- };
42
26
  if (args.options.force) {
43
- await removeMessage();
27
+ await this.removeMessage(args.options);
44
28
  }
45
29
  else {
46
30
  const result = await Cli.prompt({
@@ -50,10 +34,26 @@ class YammerMessageRemoveCommand extends YammerCommand {
50
34
  message: `Are you sure you want to remove the Yammer message ${args.options.id}?`
51
35
  });
52
36
  if (result.continue) {
53
- await removeMessage();
37
+ await this.removeMessage(args.options);
54
38
  }
55
39
  }
56
40
  }
41
+ async removeMessage(options) {
42
+ try {
43
+ const requestOptions = {
44
+ url: `${this.resource}/v1/messages/${options.id}.json`,
45
+ headers: {
46
+ accept: 'application/json;odata.metadata=none',
47
+ 'content-type': 'application/json;odata=nometadata'
48
+ },
49
+ responseType: 'json'
50
+ };
51
+ await request.delete(requestOptions);
52
+ }
53
+ catch (err) {
54
+ this.handleRejectedODataJsonPromise(err);
55
+ }
56
+ }
57
57
  }
58
58
  _YammerMessageRemoveCommand_instances = new WeakSet(), _YammerMessageRemoveCommand_initTelemetry = function _YammerMessageRemoveCommand_initTelemetry() {
59
59
  this.telemetry.push((args) => {
@@ -33,76 +33,60 @@ class YammerSearchCommand extends YammerCommand {
33
33
  __classPrivateFieldGet(this, _YammerSearchCommand_instances, "m", _YammerSearchCommand_initOptions).call(this);
34
34
  __classPrivateFieldGet(this, _YammerSearchCommand_instances, "m", _YammerSearchCommand_initValidators).call(this);
35
35
  }
36
- getAllItems(logger, args, page) {
37
- return new Promise((resolve, reject) => {
38
- const endpoint = `${this.resource}/v1/search.json?search=${formatting.encodeQueryParameter(args.options.queryText)}&page=${page}`;
39
- const requestOptions = {
40
- url: endpoint,
41
- responseType: 'json',
42
- headers: {
43
- accept: 'application/json;odata=nometadata'
44
- }
36
+ async getAllItems(logger, args, page) {
37
+ const endpoint = `${this.resource}/v1/search.json?search=${formatting.encodeQueryParameter(args.options.queryText)}&page=${page}`;
38
+ const requestOptions = {
39
+ url: endpoint,
40
+ responseType: 'json',
41
+ headers: {
42
+ accept: 'application/json;odata=nometadata'
43
+ }
44
+ };
45
+ const results = await request.get(requestOptions);
46
+ // results count should only read once
47
+ if (page === 1) {
48
+ this.summary = {
49
+ messages: results.count.messages,
50
+ topics: results.count.topics,
51
+ users: results.count.users,
52
+ groups: results.count.groups
45
53
  };
46
- request
47
- .get(requestOptions)
48
- .then((results) => {
49
- // results count should only read once
50
- if (page === 1) {
51
- this.summary = {
52
- messages: results.count.messages,
53
- topics: results.count.topics,
54
- users: results.count.users,
55
- groups: results.count.groups
56
- };
57
- }
58
- const resultMessages = results.messages.messages;
59
- const resultTopics = results.topics;
60
- const resultGroups = results.groups;
61
- const resultUsers = results.users;
62
- if (resultMessages.length > 0) {
63
- this.messages = this.messages.concat(resultMessages);
64
- if (args.options.limit && this.messages.length > args.options.limit) {
65
- this.messages = this.messages.slice(0, args.options.limit);
66
- }
67
- }
68
- if (resultTopics.length > 0) {
69
- this.topics = this.topics.concat(resultTopics);
70
- if (args.options.limit && this.topics.length > args.options.limit) {
71
- this.topics = this.topics.slice(0, args.options.limit);
72
- }
73
- }
74
- if (resultGroups.length > 0) {
75
- this.groups = this.groups.concat(resultGroups);
76
- if (args.options.limit && this.groups.length > args.options.limit) {
77
- this.groups = this.groups.slice(0, args.options.limit);
78
- }
79
- }
80
- if (resultUsers.length > 0) {
81
- this.users = this.users.concat(resultUsers);
82
- if (args.options.limit && this.users.length > args.options.limit) {
83
- this.users = this.users.slice(0, args.options.limit);
84
- }
85
- }
86
- const continueProcessing = resultMessages.length === 20 ||
87
- resultUsers.length === 20 ||
88
- resultGroups.length === 20 ||
89
- resultTopics.length === 20;
90
- if (continueProcessing) {
91
- this
92
- .getAllItems(logger, args, ++page)
93
- .then(() => {
94
- resolve();
95
- }, (err) => {
96
- reject(err);
97
- });
98
- }
99
- else {
100
- resolve();
101
- }
102
- }, (err) => {
103
- reject(err);
104
- });
105
- });
54
+ }
55
+ const resultMessages = results.messages.messages;
56
+ const resultTopics = results.topics;
57
+ const resultGroups = results.groups;
58
+ const resultUsers = results.users;
59
+ if (resultMessages.length > 0) {
60
+ this.messages = this.messages.concat(resultMessages);
61
+ if (args.options.limit && this.messages.length > args.options.limit) {
62
+ this.messages = this.messages.slice(0, args.options.limit);
63
+ }
64
+ }
65
+ if (resultTopics.length > 0) {
66
+ this.topics = this.topics.concat(resultTopics);
67
+ if (args.options.limit && this.topics.length > args.options.limit) {
68
+ this.topics = this.topics.slice(0, args.options.limit);
69
+ }
70
+ }
71
+ if (resultGroups.length > 0) {
72
+ this.groups = this.groups.concat(resultGroups);
73
+ if (args.options.limit && this.groups.length > args.options.limit) {
74
+ this.groups = this.groups.slice(0, args.options.limit);
75
+ }
76
+ }
77
+ if (resultUsers.length > 0) {
78
+ this.users = this.users.concat(resultUsers);
79
+ if (args.options.limit && this.users.length > args.options.limit) {
80
+ this.users = this.users.slice(0, args.options.limit);
81
+ }
82
+ }
83
+ const continueProcessing = resultMessages.length === 20 ||
84
+ resultUsers.length === 20 ||
85
+ resultGroups.length === 20 ||
86
+ resultTopics.length === 20;
87
+ if (continueProcessing) {
88
+ await this.getAllItems(logger, args, ++page);
89
+ }
106
90
  }
107
91
  async commandAction(logger, args) {
108
92
  this.summary = {
package/dist/utils/spo.js CHANGED
@@ -93,47 +93,6 @@ export const spo = {
93
93
  }
94
94
  });
95
95
  },
96
- waitUntilCopyJobFinished({ copyJobInfo, siteUrl, pollingInterval, resolve, reject, logger, debug, verbose }) {
97
- const requestUrl = `${siteUrl}/_api/site/GetCopyJobProgress`;
98
- const requestOptions = {
99
- url: requestUrl,
100
- headers: {
101
- 'accept': 'application/json;odata=nometadata'
102
- },
103
- data: { "copyJobInfo": copyJobInfo },
104
- responseType: 'json'
105
- };
106
- request
107
- .post(requestOptions)
108
- .then(async (resp) => {
109
- if (debug) {
110
- await logger.logToStderr('getCopyJobProgress response...');
111
- await logger.logToStderr(resp);
112
- }
113
- for (const item of resp.Logs) {
114
- const log = JSON.parse(item);
115
- // reject if progress error
116
- if (log.Event === "JobError" || log.Event === "JobFatalError") {
117
- return reject(log.Message);
118
- }
119
- }
120
- // two possible scenarios
121
- // job done = success promise returned
122
- // job in progress = recursive call using setTimeout returned
123
- if (resp.JobState === 0) {
124
- // job done
125
- if (verbose) {
126
- process.stdout.write('\n');
127
- }
128
- resolve();
129
- }
130
- else {
131
- setTimeout(() => {
132
- spo.waitUntilCopyJobFinished({ copyJobInfo, siteUrl, pollingInterval, resolve, reject, logger, debug, verbose });
133
- }, pollingInterval);
134
- }
135
- });
136
- },
137
96
  async getSpoUrl(logger, debug) {
138
97
  if (auth.service.spoUrl) {
139
98
  if (debug) {
@@ -619,12 +578,12 @@ export const spo = {
619
578
  return request.post(requestOptions);
620
579
  },
621
580
  /**
622
- * Retrieves the spo group by name.
623
- * @param webUrl Web url
624
- * @param name The name of the group
625
- * @param logger the Logger object
626
- * @param debug set if debug logging should be logged
627
- */
581
+ * Retrieves the spo group by name.
582
+ * @param webUrl Web url
583
+ * @param name The name of the group
584
+ * @param logger the Logger object
585
+ * @param debug set if debug logging should be logged
586
+ */
628
587
  async getGroupByName(webUrl, name, logger, debug) {
629
588
  if (debug) {
630
589
  await logger.logToStderr(`Retrieving the group by name ${name}`);
@@ -641,12 +600,12 @@ export const spo = {
641
600
  return groupInstance;
642
601
  },
643
602
  /**
644
- * Retrieves the role definition by name.
645
- * @param webUrl Web url
646
- * @param name the name of the role definition
647
- * @param logger the Logger object
648
- * @param debug set if debug logging should be logged
649
- */
603
+ * Retrieves the role definition by name.
604
+ * @param webUrl Web url
605
+ * @param name the name of the role definition
606
+ * @param logger the Logger object
607
+ * @param debug set if debug logging should be logged
608
+ */
650
609
  async getRoleDefinitionByName(webUrl, name, logger, debug) {
651
610
  if (debug) {
652
611
  await logger.logToStderr(`Retrieving the role definitions for ${name}`);
@@ -14,53 +14,71 @@ m365 spo file move [options]
14
14
 
15
15
  ```md definition-list
16
16
  `-u, --webUrl <webUrl>`
17
- : The URL of the site where the file is located
17
+ : The URL of the site where the file is located.
18
18
 
19
- `-s, --sourceUrl <sourceUrl>`
20
- : The server- or site-relative decoded URL of the file to move
19
+ `-s, --sourceUrl [sourceUrl]`
20
+ : The server-, site-relative or absolute decoded URL of the file to move. Specify either `sourceUrl` or `sourceId` but not both.
21
+
22
+ `-i, --sourceId [sourceId]`
23
+ : The ID of the file to move. Specify either `sourceUrl` or `sourceId` but not both.
21
24
 
22
25
  `-t, --targetUrl <targetUrl>`
23
- : Server-relative decoded URL where to move the file
26
+ : Server-relative or absolute decoded URL where to move the file.
27
+
28
+ `--newName [newName]`
29
+ : The new name of the destination file.
24
30
 
25
- `--deleteIfAlreadyExists`
26
- : If a file already exists at the targetUrl, it will be moved to the recycle bin. If omitted, the move operation will be canceled if the file already exists at the targetUrl location
31
+ `--nameConflictBehavior [nameConflictBehavior]`
32
+ : Behavior when a file or folder with the same name is already present at the destination. Possible values: `fail`, `replace`, `rename`. The default is `fail`.
27
33
 
28
- `--allowSchemaMismatch`
29
- : Ignores any missing fields in the target document library and moves the file anyway
34
+ `--retainEditorAndModified`
35
+ : Use this option to retain the editor and modified date. When not specified, these values are reset when moving to another library.
36
+
37
+ `--bypassSharedLock`
38
+ : This indicates whether a file with a share lock can still be moved. Use this option to move a file that is locked.
30
39
  ```
31
40
 
32
41
  <Global />
33
42
 
34
43
  ## Remarks
35
44
 
36
- When you move a file using the `spo file move` command, all of the versions are being moved.
45
+ All file versions are retained while moving a file.
46
+
47
+ When you specify a value for `nameConflictBehavior`, consider the following:
48
+
49
+ - `fail` will throw an error when the destination file already exists.
50
+ - `replace` will replace the destination file if it already exists.
51
+ - `rename` will add a suffix (e.g. Document1.pdf) when the destination file already exists.
37
52
 
38
53
  ## Examples
39
54
 
40
- Move file to a document library in another site collection
55
+ Move a file to a document library in another site collection by server relative URL
41
56
 
42
57
  ```sh
43
- m365 spo file move --webUrl https://contoso.sharepoint.com/sites/test1 --sourceUrl /sites/test1/Shared%20Documents/sp1.pdf --targetUrl /sites/test2/Shared%20Documents/
58
+ m365 spo file move --webUrl https://contoso.sharepoint.com/sites/project-x --sourceUrl "/sites/project-x/Shared Documents/sp1.pdf" --targetUrl "/sites/project-y/Archived documents"
44
59
  ```
45
60
 
46
- Move file to a document library in the same site collection
61
+ Move a file specified by a server-relative URL to a document library and rename it
47
62
 
48
63
  ```sh
49
- m365 spo file move --webUrl https://contoso.sharepoint.com/sites/test1 --sourceUrl /Shared%20Documents/sp1.pdf --targetUrl /sites/test1/HRDocuments/
64
+ m365 spo file move --webUrl https://contoso.sharepoint.com/sites/project-x --sourceUrl "/Shared Documents/sp1.pdf" --targetUrl "/sites/project-x/My Documents" --newName Report.pdf
50
65
  ```
51
66
 
52
- Move file to a document library in another site collection. If a file with the same name already exists in the target document library, move it to the recycle bin
67
+ Move a file to another document library and replace a file with the same name
53
68
 
54
69
  ```sh
55
- m365 spo file move --webUrl https://contoso.sharepoint.com/sites/test1 --sourceUrl /Shared%20Documents/sp1.pdf --targetUrl /sites/test2/Shared%20Documents/ --deleteIfAlreadyExists
70
+ m365 spo file move --webUrl https://contoso.sharepoint.com/sites/project-x --sourceUrl "/Shared Documents/Report project-x.pdf" --targetUrl "/sites/project-x/My Documents" --newName Report.pdf --nameConflictBehavior replace
56
71
  ```
57
72
 
58
- Move file to a document library in another site collection. Allow for schema mismatch
73
+ Move a file referenced by its ID to another document library and retain editor and modified date
59
74
 
60
- ```sh
61
- m365 spo file move --webUrl https://contoso.sharepoint.com/sites/test1 --sourceUrl /sites/test1/Shared%20Documents/sp1.pdf --targetUrl /sites/test2/Shared%20Documents/ --allowSchemaMismatch
75
+ ```sh
76
+ m365 spo file move --webUrl https://contoso.sharepoint.com/sites/project-x --sourceId b8cc341b-9c11-4f2d-aa2b-0ce9c18bcba2 --targetUrl "/sites/project-x/My Documents" --retainEditorAndModified
62
77
  ```
63
78
 
79
+ ## Response
80
+
81
+ The command won't return a response on success.
64
82
 
65
83
  ## More information
66
84